線段樹亂搞orz。
定義pre[i]為從i點往前找到第1個顏色和點i相同的點。樹狀陣列記錄max和sum。max記錄區間[l,r]內pre的最大值,sum記錄區間[l,r]內的答案總和。注意:最終的答案是取
$n*(n+1)/2-\sum _^max(pre[i],1\leq i\leq r)$,即列舉所有子區間的右節點,找最左的左節點。因此,sum[x](記錄區間[l,r])在更新的時候,sum[x的左節點]可以直接加上,而對於x的右節點要保證區間[mid+1,r]的數和max[x的左節點]取最大值。這個可以在log(n)內搞定。
然後。。就ok了。
我怕是學了個假的線段樹。
#include#include#include
#include
#include
using
namespace
std;
typedef
long
long
ll;const
int n=1e5+10
;int
n,m;
intcol[n],pre[n];
setid[n];
ll sum[n
<<2],mx[n<<2
];ll solve(
int k,int l,int
r,ll x)
void pushup(int k,int mid,int
r)void modify(int k,int l,int r,int x,int
y)
int mid=(l+r)/2
;
if (x<=mid) modify(k<<1,l,mid,x,y);else modify(k<<1|1,mid+1
,r,x,y);
pushup(k,mid,r);
}void build(int k,int l,int
r)
int mid=(l+r)/2
; build(k
<<1,l,mid);build(k<<1|1,mid+1
,r);
pushup(k,mid,r);
}set
::iterator q,l,r;
intx,to;
intmain()
build(
1,1,n);
intq,opt;
scanf("%d
",&q);
while (q--)
id[col[x]].erase(q);
col[x]=to;id[to].insert(x);
q=id[to].find(x);
l=r=q;l--;r++;
if (r!=id[to].end())
pre[x]=*l;
modify(
1,1,n,x,*l);}}
}
2016北京集訓 陣列
portal broken qwq 給你乙個陣列,每個元素有乙個顏色,要求支援兩種操作 1 修改某個元素的顏色 2 詢問這個陣列有多少個自取件內沒有重複的顏色 資料範圍 n 10 5,m 2n 顏色大小在 1 sim n 之間 這題。本來應該是乙個樹套樹題 但是為什麼一定要用樹套樹呢對吧qwq 首先...
(2016北京集訓十四) xsy1557 task
限制可以看成圖狀結構,每個任務的對物品數量的影響可以看成權值,只不過這個權值用乙個五元組來表示。那麼題意要求的就是最大權閉合子圖,網路流經典應用。1 include2 include3 include4 include5 include6 include7 define inf 1000000000...
xsy1531 北京集訓2016 魔法遊戲
orz sjk 有一棵樹,兩個人每個節點上有乙個權值,兩個人輪流選擇乙個根節點將其權值 k 除以 2,k 1 若除到 0 就刪去此根節點,它的兒子變成新根節點,刪掉最後乙個點贏。求先手還是後手必勝。首先考慮一些只有乙個根節點的樹,如果以二進位制角度看,每次除以 2,k 1 的數相當於拿掉一些二進位制...