void init() { for(int i = 1;i <= n;i++) pre[i] = i; } int findd(int x) 递归 { return pre[x] == x?x:pre[x] = findd(pre[x]); } void join(int a,int b) { int x = findd(a),y = findd(b); if(x != y) pre[x] = y; }
#include <stdio.h> const int N = 50005; int pre[N],rk[N]; /* 解题思路:father[y] = x 如果rank[y]为0 代表x 和 y属于同一种 如果rank[y]为1 代表x 吃 y 如果rank[y]为2 代表y 吃 x 本题的关键就是如何在路径压缩的过程中更新关系权值 需要总结更新公式 */ int findd(int x) { if(pre[x] == x) return x; int xx = findd(pre[x]); rk[x] = (rk[x]+rk[pre[x]])%3; pre[x] = xx; return xx; } bool ok(int n,int type,int x,int y) { if(x > n || y > n) return 0; int fx = findd(x),fy = findd(y); if(fx == fy) { if((rk[y]-rk[x]+3)%3 != type-1) return 0; return 1; } else { pre[fy] = fx; rk[fy] = (rk[x]-rk[y]+type-1+3)%3; return 1; } } int main() { int n,k; scanf("%d %d",&n,&k); for(int i = 1;i <= n;i++) { pre[i] = i; rk[i] = 0; } int cnt = 0; for(int i = 0;i < k;i++) { int d,x,y; scanf("%d %d %d",&d,&x,&y); if(!ok(n,d,x,y)) cnt++; } printf("%d\n",cnt); return 0; }
struct ST { int mm[100005],dp[100005][20]; void init() { mm[0] = -1; for(int i = 1;i <= n;i++) { mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1]; dp[i][0] = a[i]; } for(int j = 1;j <= mm[n];j++) { for(int i = 1;i+(1<<j)-1 <= n;i++) dp[i][j] = min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]); } } int query(int a,int b) { if(a > b) swap(a,b); int k = mm[b-a+1]; return min(dp[a][k],dp[b-(1<<k)+1][k]); } }st;
//同一维一样 用dp[row][col][i][j]表示(row,col)到(row+2^i,col+2^j)矩形内的最小值 int a[305][305],mm[305],dp[305][305][9][9]; void init(int n,int m) { for(int i = 1;i <= 300;i++) mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1]; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) dp[i][j][0][0] = a[i][j]; } for(int i = 0;i <= mm[n];i++) { for(int j = 0;j <= mm[m];j++) { if(i==0 && j==0) continue; for(int row = 1;row+(1<<i)-1 <= n;row++) { for(int col = 1;col+(1<<j)-1 <= m;col++) { if(i) dp[row][col][i][j] = max(dp[row][col][i-1][j],dp[row+(1<<(i-1))][col][i-1][j]); else dp[row][col][i][j] = max(dp[row][col][i][j-1],dp[row][col+(1<<(j-1))][i][j-1]); } } } } } int rmq(int x1,int y1,int x2,int y2) { int k1 = mm[x2-x1+1],k2 = mm[y2-y1+1]; x2 = x2-(1<<k1)+1,y2 = y2-(1<<k2)+1; return max(max(dp[x1][y1][k1][k2],dp[x1][y2][k1][k2]),max(dp[x2][y1][k1][k2],dp[x2][y2][k1][k2])); }
#include<bits/stdc++.h> using namespace std; stack<long long> s; long long a[100005]; int main() { int n; while(scanf("%d",&n) && n) { while(!s.empty()) s.pop(); long long ans = 0; for(int i = 1;i <= n;i++) scanf("%lld",&a[i]); a[n+1] = 0; for(int i = 1;i <= n+1;i++) { while(!s.empty() && a[s.top()] > a[i]) { int temp = s.top(); s.pop(); int len = s.empty()?i-1:i-s.top()-1; ans = max(ans,len*a[temp]); } s.push(i); } printf("%lld\n",ans); } return 0; } //HDU1506
#include<bits/stdc++.h> using namespace std; struct st { int num,t; }s; deque<st> q; int n,x; int main() { while(~scanf("%d",&n)) { while(!q.empty()) q.pop_back(); int out = 1,cnt = 1; for(int i = 1;i <= n;i++) { scanf("%d",&x); switch(x) { case 1: int tt; scanf("%d",&tt); s.t = tt-i; s.num = cnt++; while(!q.empty() && q.back().t <= s.t) q.pop_back(); q.push_back(s); break; case 2: if(q.front().num == out++) q.pop_front(); break; case 3: printf("%d\n",q.front().t+i); } } } return 0; } //XDOJ1156
int tree[50005],n; inline int lowbit(int x) { return x & (-x); } void update(int pos,int x) { while(pos <= n) { tree[pos] += x; pos += lowbit(pos); } } int getsum(int pos) { int sum = 0; while(pos > 0) { sum += tree[pos]; pos -= lowbit(pos); } return sum; }
int tree[1005][1005] = {0},a[1005][1005] = {0}; int lowbit(int x) { return x&(-x); } void update(int x,int y,int w) { for(int i = x;i <= 1001;i += lowbit(i)) { for(int j = y;j <= 1001;j += lowbit(j)) tree[i][j] += w; } } int getsum(int x,int y) { int ans = 0; for(int i = x;i > 0;i -= lowbit(i)) { for(int j = y;j > 0;j -= lowbit(j)) ans += tree[i][j]; } return ans; }
#include<bits/stdc++.h> using namespace std; #define N 100005 int n,m,tree[20][N],sorted[N],toleft[20][N]; void build(int l,int r,int dep) { if(l == r)return; int mid = (l+r)/2,same = mid-l+1; for(int i = l;i <= r;i++) { if(tree[dep][i] < sorted[mid]) same--; } int lpos = l,rpos = mid+1; for(int i = l;i <= r;i++) { if(tree[dep][i] < sorted[mid]) tree[dep+1][lpos++] = tree[dep][i]; else if(tree[dep][i] == sorted[mid] && same > 0) { tree[dep+1][lpos++] = tree[dep][i]; same--; } else tree[dep+1][rpos++] = tree[dep][i]; toleft[dep][i] = toleft[dep][l-1]+lpos-l; } build(l,mid,dep+1); build(mid+1,r,dep+1); } int query(int l,int r,int ql,int qr,int dep,int k) { if(ql == qr) return tree[dep][ql]; int mid = (l+r)/2,cnt = toleft[dep][qr]-toleft[dep][ql-1]; if(cnt >= k) { int ll = l+toleft[dep][ql-1]-toleft[dep][l-1],rr = ll+cnt-1; return query(l,mid,ll,rr,dep+1,k); } else { int rr = qr+toleft[dep][r]-toleft[dep][qr],ll = rr-(qr-ql-cnt); return query(mid+1,r,ll,rr,dep+1,k-cnt); } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i = 1;i <= n;i++) { scanf("%d",&tree[0][i]); sorted[i] = tree[0][i]; } sort(sorted+1,sorted+n+1); build(1,n,0); while(m--) { int l,r,k; scanf("%d%d%d",&l,&r,&k); printf("%d\n",query(1,n,l,r,0,k)); } } return 0; }
int n,k,root,son[10005],vis[10005],minn,ans,sum,dis[10005],dep[10005]; struct xx { int to,w; xx(int a,int b):to(a),w(b){}; }; vector<xx> v[10005]; void dfsroot(int now,int pre) { son[now] = 1; int maxx = 0; for(int i = 0;i < v[now].size();i++) { int t = v[now][i].to,w = v[now][i].w; if(t == pre || vis[t]) continue; dfsroot(t,now); son[now] += son[t]; maxx = max(maxx,son[t]); } maxx = max(maxx,sum-son[now]); if(maxx < minn) { minn = maxx; root = now; } } void dfsdep(int now,int pre) { dep[++dep[0]] = dis[now]; for(int i = 0;i < v[now].size();i++) { int t = v[now][i].to,w = v[now][i].w; if(t == pre || vis[t]) continue; dis[t] = dis[now]+w; dfsdep(t,now); } } int calc(int now,int w) { dis[now] = w; dep[0] = 0; dfsdep(now,0); sort(dep+1,dep+dep[0]+1); int l = 1,r = dep[0],cnt = 0; while(l < r) { if(dep[l]+dep[r] <= k) { cnt += r-l; l++; } else r--; } return cnt; } void solve(int now) { ans += calc(now,0); vis[now] = 1; for(int i = 0;i < v[now].size();i++) { int t = v[now][i].to,w = v[now][i].w; if(vis[t]) continue; ans -= calc(t,w); minn = 1e9; sum = son[t]; dfsroot(t,0); solve(root); } } int main() { while(scanf("%d%d",&n,&k)) { if(n == 0 || k == 0) break; ans = 0,sum = n; memset(vis,0,sizeof(vis)); for(int i = 1;i <= n;i++) v[i].clear(); for(int i = 1;i < n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); v[x].push_back(xx(y,z)); v[y].push_back(xx(x,z)); } minn = 1e9; dfsroot(1,0); solve(root); printf("%d\n",ans); } return 0; }
int n,k,root,son[100005],vis[100005],dep[100005],id[1000005],minn,ans1,ans2,sum; long long a[100005],inv[1000005],mp[1000005]; vector<int> v[100005]; void dfsroot(int now,int pre) { son[now] = 1; int maxx = 0; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre || vis[t]) continue; dfsroot(t,now); son[now] += son[t]; maxx = max(maxx,son[t]); } maxx = max(maxx,sum-son[now]); if(maxx < minn) { minn = maxx; root = now; } } void dfsdep(int now,int pre,long long x) { dep[++dep[0]] = x*a[now]%MOD; id[dep[0]] = now; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre || vis[t]) continue; dfsdep(t,now,x*a[now]%MOD); } } void update(int now,int x,int y) { int t = mp[inv[x*a[now]%MOD]*k%MOD]; if(!t) return; if(t > y) swap(t,y); if(t < ans1 || t == ans1 && y < ans2) { ans1 = t; ans2 = y; } } void solve(int now) { vis[now] = 1; mp[1] = now; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(vis[t]) continue; dep[0] = 0; dfsdep(t,now,1); for(int j = 1;j <= dep[0];j++) update(now,dep[j],id[j]); for(int j = 1;j <= dep[0];j++) { if(!mp[dep[j]] || mp[dep[j]] > id[j]) mp[dep[j]] = id[j]; } } mp[1] = 0; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(vis[t]) continue; dep[0] = 0; dfsdep(t,now,1); for(int j = 1;j <= dep[0];j++) mp[dep[j]] = 0; } for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(vis[t]) continue; minn = 1e9; sum = son[t]; dfsroot(t,0); solve(root); } } int main() { inv[1] = 1; for(int i = 2;i < MOD;i++) inv[i] = (MOD-MOD/i)*inv[MOD%i]%MOD; while(~scanf("%d%d",&n,&k)) { ans1 = 1e9,ans2 = 0; memset(vis,0,sizeof(vis)); for(int i = 1;i <= n;i++) v[i].clear(); for(int i = 1;i <= n;i++) scanf("%lld",&a[i]); for(int i = 1;i < n;i++) { int x,y; scanf("%d%d",&x,&y); v[x].push_back(y); v[y].push_back(x); } minn = 1e9; sum = n; dfsroot(1,0); solve(root); if(ans1 == 1e9) printf("No solution\n"); else printf("%d %d\n",ans1,ans2); } return 0; }
int n,maxx,tree[100005],ans[100005]; struct xx { int x,y,z,id; xx(int a,int b,int c,int d):x(a),y(b),z(c),id(d){}; xx(){}; }a[100005],b[100005]; inline lowbit(int x) { return x&-x; } void add(int pos,int x) { while(pos <= maxx) { tree[pos] += x; pos += lowbit(pos); } } int getsum(int pos) { int ans = 0; while(pos > 0) { ans += tree[pos]; pos -= lowbit(pos); } return ans; } bool cmp1(xx a,xx b) { if(a.x != b.x) return a.x < b.x; if(a.y != b.y) return a.y < b.y; return a.z < b.z; } bool cmp2(xx a,xx b) { if(a.y != b.y) return a.y < b.y; return a.id < b.id; } void cdq(int l,int r) { if(l == r) return; int mid = (l+r)/2; int cnt = 0; for(int i = l;i <= mid;i++) b[++cnt] = xx(0,a[i].y,a[i].z,0); for(int i = mid+1;i <= r;i++) b[++cnt] = xx(0,a[i].y,a[i].z,a[i].id); sort(b+1,b+1+cnt,cmp2); for(int i = 1;i <= cnt;i++) { if(b[i].id == 0) add(b[i].z,1); else ans[b[i].id] += getsum(b[i].z); } for(int i = 1;i <= cnt;i++) { if(b[i].id == 0) add(b[i].z,-1); } cdq(l,mid); cdq(mid+1,r); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); maxx = 0; for(int i = 1;i <= n;i++) { scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); a[i].id = i; maxx = max(maxx,a[i].z); } sort(a+1,a+1+n,cmp1); memset(ans,0,sizeof(ans)); int cnt = 0; for(int i = n-1;i >= 1;i--) { if(a[i].x == a[i+1].x && a[i].y == a[i+1].y && a[i].z == a[i+1].z) cnt++; else cnt = 0; ans[a[i].id] += cnt; } cdq(1,n); for(int i = 1;i <= n;i++) printf("%d\n",ans[i]); } return 0; }
//点权,修改路径点权,查询单点权 #include<bits/stdc++.h> using namespace std; #define N 50005 int n,m,q,cnt,a[N],top[N],fa[N],dep[N],num[N],p[N],fp[N],son[N]; vector<int> v[N]; char s[10]; struct segtree { int l,r; long long x,lazy; }tree[4*N]; inline void pushup(int pos) { tree[pos].x = tree[pos<<1].x+tree[pos<<1|1].x; } inline void pushdown(int pos) { if(tree[pos].lazy) { tree[pos<<1].x += (tree[pos<<1].r-tree[pos<<1].l+1)*tree[pos].lazy; tree[pos<<1|1].x += (tree[pos<<1|1].r-tree[pos<<1|1].l+1)*tree[pos].lazy; tree[pos<<1].lazy += tree[pos].lazy; tree[pos<<1|1].lazy += tree[pos].lazy; tree[pos].lazy = 0; } } void build(int pos,int l,int r) { tree[pos].l = l; tree[pos].r = r; tree[pos].lazy = 0; if(l == r) { tree[pos].x = a[fp[l]]; return; } int mid = (l+r)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pushup(pos); } void update(int pos,int l,int r,long long x) { if(r < tree[pos].l || tree[pos].r < l) return; if(l <= tree[pos].l && tree[pos].r <= r) { tree[pos].x += (tree[pos].r-tree[pos].l+1)*x; tree[pos].lazy += x; return; } pushdown(pos); update(pos<<1,l,r,x); update(pos<<1|1,l,r,x); pushup(pos); } long long getsum(int pos,int l,int r) { if(r < tree[pos].l || tree[pos].r < l) return 0; if(l <= tree[pos].l && tree[pos].r <= r) return tree[pos].x; pushdown(pos); return getsum(pos<<1,l,r)+getsum(pos<<1|1,l,r); } void dfs(int now,int pre,int d) { dep[now] = d; fa[now] = pre; num[now] = 1; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; dfs(t,now,d+1); num[now] += num[t]; if(son[now] == -1 || num[t] > num[son[now]]) son[now] = t; } } void getpos(int now,int sp) { top[now] = sp; p[now] = ++cnt; fp[p[now]] = now; if(son[now] == -1) return; getpos(son[now],sp); for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t != son[now] && t != fa[now]) getpos(t,t); } } void change(int u,int v,int x) { int f1 = top[u],f2 = top[v]; while(f1 != f2) { if(dep[f1] < dep[f2]) { swap(f1,f2); swap(u,v); } update(1,p[f1],p[u],x); u = fa[f1]; f1 = top[u]; } if(dep[u] > dep[v]) swap(u,v); update(1,p[u],p[v],x); } int main() { while(~scanf("%d%d%d",&n,&m,&q)) { memset(son,-1,sizeof(son)); memset(tree,0,sizeof(tree)); for(int i = 1;i <= n;i++) v[i].clear(); cnt = 0; for(int i = 1;i <= n;i++) scanf("%d",&a[i]); while(m--) { int x,y; scanf("%d%d",&x,&y); v[x].push_back(y); v[y].push_back(x); } dfs(1,0,0); getpos(1,1); build(1,1,cnt); while(q--) { scanf("%s",s); if(s[0] == 'Q') { int x; scanf("%d",&x); printf("%lld\n",getsum(1,p[x],p[x])); } else { int x,y,z; scanf("%d%d%d",&x,&y,&z); if(s[0] == 'D') z = -z; change(x,y,z); } } } return 0; }
#include<bits/stdc++.h> #define N 10005 using namespace std; int n,m,q,cnt,a[N],val[N],top[N],fa[N],dep[N],num[N],p[N],fp[N],son[N],e[N][3]; struct segtree { int l,r,x; }tree[4*N]; vector<int> v[N]; char s[10]; void pushup(int pos) { tree[pos].x = max(tree[pos<<1].x,tree[pos<<1|1].x); } void build(int pos,int l,int r) { tree[pos].l = l; tree[pos].r = r; if(l == r) { tree[pos].x = val[l]; return; } int mid = (l+r)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pushup(pos); } void update(int pos,int l,int r,int x) { if(r < tree[pos].l || tree[pos].r < l) return; if(l <= tree[pos].l && tree[pos].r <= r) { tree[pos].x = x; return; } update(pos<<1,l,r,x); update(pos<<1|1,l,r,x); pushup(pos); } int query(int pos,int l,int r) { if(r < tree[pos].l || tree[pos].r < l) return 0; if(l <= tree[pos].l && tree[pos].r <= r) return tree[pos].x; return max(query(pos<<1,l,r),query(pos<<1|1,l,r)); } void dfs(int now,int pre,int d) { dep[now] = d; fa[now] = pre; num[now] = 1; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; dfs(t,now,d+1); num[now] += num[t]; if(son[now] == -1 || num[t] > num[son[now]]) son[now] = t; } } void getpos(int now,int sp) { top[now] = sp; p[now] = ++cnt; fp[p[now]] = now; if(son[now] == -1) return; getpos(son[now],sp); for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t != son[now] && t != fa[now]) getpos(t,t); } } int solve(int u,int v) { int f1 = top[u],f2 = top[v],t = 0; while(f1 != f2) { if(dep[f1] < dep[f2]) { swap(f1,f2); swap(u,v); } t = max(t,query(1,p[f1],p[u])); u = fa[f1]; f1 = top[u]; } if(u == v) return t; if(dep[u] > dep[v]) swap(u,v); return max(t,query(1,p[son[u]],p[v])); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); memset(son,-1,sizeof(son)); for(int i = 1;i <= n;i++) v[i].clear(); cnt = 0; for(int i = 1;i < n;i++) { scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]); v[e[i][0]].push_back(e[i][1]); v[e[i][1]].push_back(e[i][0]); } dfs(1,0,0); getpos(1,1); for(int i = 1;i < n;i++) { if(dep[e[i][0]] > dep[e[i][1]]) swap(e[i][0],e[i][1]); val[p[e[i][1]]] = e[i][2]; } build(1,1,cnt); while(scanf("%s",s)) { if(s[0] == 'D') break; int x,y; scanf("%d%d",&x,&y); if(s[0] == 'Q') printf("%d\n",solve(x,y)); else update(1,p[e[x][1]],p[e[x][1]],y); } } return 0; }
struct segtree { int l,r; long long x,lazy; }tree[400005]; inline void pushup(int pos) { tree[pos].x = tree[pos<<1].x+tree[pos<<1|1].x; } inline void pushdown(int pos) { if(tree[pos].lazy) { tree[pos<<1].x += (tree[pos<<1].r-tree[pos<<1].l+1)*tree[pos].lazy; tree[pos<<1|1].x += (tree[pos<<1|1].r-tree[pos<<1|1].l+1)*tree[pos].lazy; tree[pos<<1].lazy += tree[pos].lazy; tree[pos<<1|1].lazy += tree[pos].lazy; tree[pos].lazy = 0; } } void build(int pos,int l,int r) { tree[pos].l = l; tree[pos].r = r; tree[pos].lazy = 0; if(l == r) { tree[pos].x = a[l]; return; } int mid = (l+r)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pushup(pos); } void update(int pos,int l,int r,long long x) { if(r < tree[pos].l || tree[pos].r < l) return; if(l <= tree[pos].l && tree[pos].r <= r) { tree[pos].x = (tree[pos].r-tree[pos].l+1)*x; tree[pos].lazy = x; return; } pushdown(pos); update(pos<<1,l,r,x); update(pos<<1|1,l,r,x); pushup(pos); } long long getsum(int pos,int l,int r) { if(r < tree[pos].l || tree[pos].r < l) return 0; if(l <= tree[pos].l && tree[pos].r <= r) return tree[pos].x; pushdown(pos); return getsum(pos<<1,l,r)+getsum(pos<<1|1,l,r); }
int n,k,q,cnt = 0,a[100005]; struct segtree { int l,r,x,lazy; segtree *lson,*rson; }*root; segtree *newnode(int l,int r) { segtree *t = new segtree; t->l = l; t->r = r; t->lson = NULL; t->rson = NULL; t->lazy = 0; t->x = a[l]; return t; } segtree *newlson(segtree *pos) { int mid = (pos->l+pos->r)/2; return newnode(pos->l,mid); } segtree *newrson(segtree *pos) { int mid = (pos->l+pos->r)/2; return newnode(mid+1,pos->r); } void pushup(segtree *pos) { if(!pos->lson) pos->lson = newlson(pos); if(!pos->rson) pos->rson = newrson(pos); pos->x = min(pos->lson->x,pos->rson->x); } void pushdown(segtree *pos) { if(!pos->lson) pos->lson = newlson(pos); if(!pos->rson) pos->rson = newrson(pos); if(pos->lazy) { pos->lson->x = pos->lazy; pos->rson->x = pos->lazy; pos->lson->lazy = pos->lazy; pos->rson->lazy = pos->lazy; pos->lazy = 0; } } void update(segtree *pos,int l,int r,int x) { if(r < pos->l || pos->r < l) return; if(l <= pos->l && pos->r <= r) { pos->x = x; pos->lazy = x; return; } pushdown(pos); update(pos->lson,l,r,x); update(pos->rson,l,r,x); pushup(pos); } int getmin(segtree *pos,int l,int r) { if(r < pos->l || pos->r < l) return 1e9; if(l <= pos->l && pos->r <= r) return pos->x; pushdown(pos); return min(getmin(pos->lson,l,r),getmin(pos->rson,l,r)); }
#include<bits/stdc++.h> using namespace std; int n,m; long long a[100005]; struct segtree { int l,r; long long x,sum; }tree[400005]; inline void pushup(int pos) { tree[pos].x = max(tree[pos<<1].x,tree[pos<<1|1].x); tree[pos].sum = tree[pos<<1].sum+tree[pos<<1|1].sum; } void build(int pos,int l,int r) { tree[pos].l = l; tree[pos].r = r; if(l >= r) { tree[pos].x = a[l]; tree[pos].sum = a[l]; return; } int mid = (l+r)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pushup(pos); } void edit(int pos,int l,int r,long long x,int t) { if(t < l || t > r) return; if(l == r) { tree[pos].x = x; tree[pos].sum = x; return; } int mid = (l+r)/2; edit(pos<<1,l,mid,x,t); edit(pos<<1|1,mid+1,r,x,t); pushup(pos); } void mod(int pos,int l,int r,long long x) { if(r < tree[pos].l || tree[pos].r < l || tree[pos].x < x) return; if(tree[pos].l == tree[pos].r) { tree[pos].x %= x; tree[pos].sum = tree[pos].x; return; } mod(pos<<1,l,r,x); mod(pos<<1|1,l,r,x); pushup(pos); } long long getsum(int pos,int l,int r) { if(r < tree[pos].l || tree[pos].r < l) return 0; if(l <= tree[pos].l && tree[pos].r <= r) return tree[pos].sum; return getsum(pos<<1,l,r)+getsum(pos<<1|1,l,r); } int main() { ios::sync_with_stdio(false); cin >> n >> m; for(int i = 1;i <= n;i++) cin >> a[i]; build(1,1,n); for(int i = 1;i <= m;i++) { int z,l,r,x; cin >> z; if(z == 1) { cin >> l >> r; cout << getsum(1,l,r) << endl; } else if(z == 2) { cin >> l >> r >> x; mod(1,l,r,x); } else { cin >> l >> x; edit(1,1,n,x,l); } } return 0; } //CF438D
#include<bits/stdc++.h> using namespace std; int n,m; long long a[100005]; struct segtree { int l,r; long long ma,mi,sum,lazy; }tree[400005]; inline void pushup(int pos) { tree[pos].ma = max(tree[pos<<1].ma,tree[pos<<1|1].ma); tree[pos].mi = min(tree[pos<<1].mi,tree[pos<<1|1].mi); tree[pos].sum = tree[pos<<1].sum+tree[pos<<1|1].sum; } inline void pushdown(int pos) { if(tree[pos].lazy) { long long t = tree[pos].lazy; tree[pos<<1].lazy += t; tree[pos<<1|1].lazy += t; tree[pos<<1].mi += t; tree[pos<<1|1].mi += t; tree[pos<<1].ma += t; tree[pos<<1|1].ma += t; tree[pos<<1].sum += (tree[pos<<1].r-tree[pos<<1].l+1)*t; tree[pos<<1|1].sum += (tree[pos<<1|1].r-tree[pos<<1|1].l+1)*t; tree[pos].lazy = 0; } } void build(int pos,int l,int r) { tree[pos].l = l; tree[pos].r = r; tree[pos].lazy = 0; if(l == r) { tree[pos].mi = a[l]; tree[pos].ma = a[l]; tree[pos].sum = a[l]; return; } int mid = (l+r)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pushup(pos); } long long getsum(int pos,int l,int r) { if(r < tree[pos].l || tree[pos].r < l) return 0; if(l <= tree[pos].l && tree[pos].r <= r) return tree[pos].sum; pushdown(pos); return getsum(pos<<1,l,r)+getsum(pos<<1|1,l,r); } void update(int pos,int l,int r,long long x) { if(r < tree[pos].l || tree[pos].r < l) return; if(l <= tree[pos].l && tree[pos].r <= r) { tree[pos].mi += x; tree[pos].ma += x; tree[pos].sum += (tree[pos].r-tree[pos].l+1)*x; tree[pos].lazy += x; return; } pushdown(pos); update(pos<<1,l,r,x); update(pos<<1|1,l,r,x); pushup(pos); } void sq(int pos,int l,int r) { if(r < tree[pos].l || tree[pos].r < l) return; if(l <= tree[pos].l && tree[pos].r <= r && (long long)sqrt(tree[pos].ma)-(long long)sqrt(tree[pos].mi) == tree[pos].ma-tree[pos].mi) { long long t = tree[pos].ma-(long long)sqrt(tree[pos].ma); tree[pos].mi -= t; tree[pos].ma -= t; tree[pos].sum -= (tree[pos].r-tree[pos].l+1)*t; tree[pos].lazy -= t; return; } pushdown(pos); sq(pos<<1,l,r); sq(pos<<1|1,l,r); pushup(pos); } int main() { ios::sync_with_stdio(0); cin >> n >> m; for(int i = 1;i <= n;i++) cin >> a[i]; build(1,1,n); for(int i = 1;i <= m;i++) { int z,l,r,x; cin >> z >> l >> r; if(z == 1) { cin >> x; update(1,l,r,x); } else if(z == 2) sq(1,l,r); else cout << getsum(1,l,r) << endl; } return 0; } //UOJ228
#include<bits/stdc++.h> using namespace std; int n,m; long long a[1000005]; struct segtree { int l,r,max1,max2,num; long long sum; }tree[4000005]; inline void pushup(int pos) { tree[pos].max1 = max(tree[pos<<1].max1,tree[pos<<1|1].max1); tree[pos].sum = tree[pos<<1].sum+tree[pos<<1|1].sum; tree[pos].num = 0; tree[pos].max2 = max(tree[pos<<1].max2,tree[pos<<1|1].max2); if(tree[pos].max1 == tree[pos<<1].max1) tree[pos].num += tree[pos<<1].num; else tree[pos].max2 = max(tree[pos].max2,tree[pos<<1].max1); if(tree[pos].max1 == tree[pos<<1|1].max1) tree[pos].num += tree[pos<<1|1].num; else tree[pos].max2 = max(tree[pos].max2,tree[pos<<1|1].max1); } inline void pushdown(int pos) { if(tree[pos].max1 < tree[pos<<1].max1) { tree[pos<<1].sum -= (long long)tree[pos<<1].num*(tree[pos<<1].max1-tree[pos].max1); tree[pos<<1].max1 = tree[pos].max1; } if(tree[pos].max1 < tree[pos<<1|1].max1) { tree[pos<<1|1].sum -= (long long)tree[pos<<1|1].num*(tree[pos<<1|1].max1-tree[pos].max1); tree[pos<<1|1].max1 = tree[pos].max1; } } void build(int pos,int l,int r) { tree[pos].l = l; tree[pos].r = r; if(l == r) { scanf("%d",&tree[pos].max1); tree[pos].sum = tree[pos].max1; tree[pos].max2 = -1; tree[pos].num = 1; return; } int mid = (l+r)/2; build(pos<<1,l,mid); build(pos<<1|1,mid+1,r); pushup(pos); } void update(int pos,int l,int r,int x) { if(r < tree[pos].l || tree[pos].r < l || x >= tree[pos].max1) return; if(l <= tree[pos].l && tree[pos].r <= r && tree[pos].max2 < x) { tree[pos].sum -= (long long)tree[pos].num*(tree[pos].max1-x); tree[pos].max1 = x; return; } pushdown(pos); update(pos<<1,l,r,x); update(pos<<1|1,l,r,x); pushup(pos); } long long getsum(int pos,int l,int r) { if(r < tree[pos].l || tree[pos].r < l) return 0; if(l <= tree[pos].l && tree[pos].r <= r) return tree[pos].sum; pushdown(pos); return getsum(pos<<1,l,r)+getsum(pos<<1|1,l,r); } int getmax(int pos,int l,int r) { if(r < tree[pos].l || tree[pos].r < l) return 0; if(l <= tree[pos].l && tree[pos].r <= r) return tree[pos].max1; pushdown(pos); return max(getmax(pos<<1,l,r),getmax(pos<<1|1,l,r)); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); build(1,1,n); for(int i = 1;i <= m;i++) { int z,l,r,x; scanf("%d%d%d",&z,&l,&r); if(z == 0) { scanf("%d",&x); update(1,l,r,x); } else if(z == 1) printf("%d\n",getmax(1,l,r)); else printf("%lld\n",getsum(1,l,r)); } } return 0; } //HDU5306
#include<bits/stdc++.h> #define INF 0x3f3f3f3f #define ls pos<<1 #define rs pos<<1|1 using namespace std; int n,m; char s[10]; long long a[1000005]; struct segtree { int l,r,nmax,pmax,nlazy,plazy,ncov,pcov; }tree[4000005]; inline void pushup(int pos) { tree[pos].nmax = max(tree[ls].nmax,tree[rs].nmax); tree[pos].pmax = max(tree[ls].pmax,tree[rs].pmax); } inline void pushdown(int pos) { tree[ls].pmax = max(tree[ls].pmax,max(tree[pos].pcov,tree[pos].plazy+tree[ls].nmax)); tree[rs].pmax = max(tree[rs].pmax,max(tree[pos].pcov,tree[pos].plazy+tree[rs].nmax)); if(tree[pos].ncov == -INF) { tree[ls].nmax += tree[pos].nlazy; tree[rs].nmax += tree[pos].nlazy; if(tree[ls].ncov == -INF) { tree[ls].plazy = max(tree[ls].plazy,tree[ls].nlazy+tree[pos].plazy); tree[ls].nlazy += tree[pos].nlazy; } else { tree[ls].pcov = max(tree[ls].pcov,tree[ls].ncov+tree[pos].plazy); tree[ls].ncov = tree[ls].nmax; } if(tree[rs].ncov == -INF) { tree[rs].plazy = max(tree[rs].plazy,tree[rs].nlazy+tree[pos].plazy); tree[rs].nlazy += tree[pos].nlazy; } else { tree[rs].pcov = max(tree[rs].pcov,tree[rs].ncov+tree[pos].plazy); tree[rs].ncov = tree[rs].nmax; } } else { if(tree[ls].ncov == -INF) tree[ls].plazy = max(tree[ls].plazy,tree[ls].nlazy+tree[pos].plazy); else tree[ls].pcov = max(tree[ls].pcov,tree[ls].nmax+tree[pos].plazy); if(tree[rs].ncov == -INF) tree[rs].plazy = max(tree[rs].plazy,tree[rs].nlazy+tree[pos].plazy); else tree[rs].pcov = max(tree[rs].pcov,tree[rs].nmax+tree[pos].plazy); tree[ls].nmax = tree[pos].ncov; tree[rs].nmax = tree[pos].ncov; tree[ls].ncov = tree[pos].ncov; tree[rs].ncov = tree[pos].ncov; tree[ls].pcov = max(tree[ls].pcov,tree[pos].pcov); tree[rs].pcov = max(tree[rs].pcov,tree[pos].pcov); } tree[pos].nlazy = 0; tree[pos].plazy = 0; tree[pos].ncov = -INF; tree[pos].pcov = -INF; } void build(int pos,int l,int r) { tree[pos].l = l; tree[pos].r = r; tree[pos].ncov = -INF; tree[pos].pcov = -INF; tree[pos].nlazy = 0; tree[pos].plazy = 0; if(l == r) { scanf("%d",&tree[pos].nmax); tree[pos].pmax = tree[pos].nmax; return; } int mid = (l+r)/2; build(ls,l,mid); build(rs,mid+1,r); pushup(pos); } long long getans(int pos,int l,int r,int t) { if(r < tree[pos].l || tree[pos].r < l) return -INF; if(l <= tree[pos].l && tree[pos].r <= r) return t?tree[pos].pmax:tree[pos].nmax; pushdown(pos); return max(getans(ls,l,r,t),getans(rs,l,r,t)); } void update1(int pos,int l,int r,int x) { if(r < tree[pos].l || tree[pos].r < l) return; if(l <= tree[pos].l && tree[pos].r <= r) { tree[pos].nmax += x; tree[pos].pmax = max(tree[pos].pmax,tree[pos].nmax); if(tree[pos].ncov == -INF) { tree[pos].nlazy += x; tree[pos].plazy = max(tree[pos].plazy,tree[pos].nlazy); } else { tree[pos].ncov = tree[pos].nmax; tree[pos].pcov = max(tree[pos].pcov,tree[pos].ncov); } return; } pushdown(pos); update1(ls,l,r,x); update1(rs,l,r,x); pushup(pos); } void update2(int pos,int l,int r,int x) { if(r < tree[pos].l || tree[pos].r < l) return; if(l <= tree[pos].l && tree[pos].r <= r) { tree[pos].nmax = x; tree[pos].pmax = max(tree[pos].pmax,tree[pos].nmax); tree[pos].ncov = x; tree[pos].pcov = max(tree[pos].pcov,tree[pos].ncov); return; } pushdown(pos); update2(ls,l,r,x); update2(rs,l,r,x); pushup(pos); } int main() { scanf("%d",&n); build(1,1,n); scanf("%d",&m); for(int i = 1;i <= m;i++) { int l,r,x; scanf("%s%d%d",s,&l,&r); if(s[0] == 'Q') printf("%d\n",getans(1,l,r,0)); else if(s[0] == 'A') printf("%d\n",getans(1,l,r,1)); else if(s[0] == 'P') { scanf("%d",&x); update1(1,l,r,x); } else { scanf("%d",&x); update2(1,l,r,x); } } return 0; } //TYVJ1518
#include<bits/stdc++.h> using namespace std; int n,m,a[200005],cnt[200005],next[200005],belong[200005],l[1005],r[1005]; void build() { int len = sqrt(n); int num = (n+len-1)/len; if(n%len) num++; for(int i = 1;i <= num;i++) { l[i] = (i-1)*len+1; r[i] = i*len; } r[num] = n; for(int i = 1;i <= n;i++) belong[i] = (i-1)/len+1; for(int i = n;i >= 1;i--) { int t = i+a[i]; if(t > n) { cnt[i] = 1; next[i] = -1; } else if(belong[i] == belong[t]) { cnt[i] = cnt[t]+1; next[i] = next[t]; } else { cnt[i] = 1; next[i] = t; } } } void update(int pos,int x) { a[pos] = x; for(int i = pos;i >= l[belong[pos]];i--) { int t = i+a[i]; if(t > n) { cnt[i] = 1; next[i] = -1; } else if(belong[i] == belong[t]) { cnt[i] = cnt[t]+1; next[i] = next[t]; } else { cnt[i] = 1; next[i] = t; } } } int getsum(int x) { int ans = cnt[x]; while(next[x] > 0) { x = next[x]; ans += cnt[x]; } return ans; } int main() { ios::sync_with_stdio(false); scanf("%d",&n); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); build(); scanf("%d",&m); while(m--) { int x,y,z; scanf("%d",&x); if(x == 1) { scanf("%d",&y); printf("%d\n",getsum(y+1)); } else { scanf("%d%d",&y,&z); update(y+1,z); } } return 0; }
int a[30005],num[30005],n,m; long long ans[30005]; struct node { int l,r,num,belong; friend bool operator<(node a,node b) { if(a.belong == b.belong) return a.r < b.r; return a.l < b.l; } }query[30005]; int main() { while(~scanf("%d%d",&n,&m)) { int size = sqrt(n); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); for(int i = 1;i <= m;i++) { scanf("%d%d",&query[i].l,&query[i].r); query[i].num = i; query[i].belong = (query[i].l-1)/size+1; } sort(query+1,query+1+m); memset(num,0,sizeof(num)); int ll = 1,rr = 1; LL now = 1; num[a[1]]++; for(int i = 1;i <= m;i++) { while(rr < query[i].r) { rr++; num[a[rr]]++; //now = ; } while(ll > query[i].l) { ll--; num[a[ll]]++; //now = ; } while(ll < query[i].l) { //now = ; num[a[ll]]--; ll++; } while(rr > query[i].r) { //now = ; num[a[rr]]--; rr--; } ans[query[i].num] = now; } for(int i = 1;i <= m;i++) printf("%lld\n",ans[i]); } return 0; }
//1:INSERT post tot c1,c2,...ctot :在当前数列的第pos个数字后插入tot个数字 //2:DELETE pos tot : 从当前数列的第pos个数字开始连续 删除tot个数字 //3:MAKE-SAME pos tot c :将当前数列的第pos个数字开始连续的tot个数字统一修改为c //4:REVERSE pos tot : 翻转当前数列的第pos个数字来说的连续的tot个数字 //5:GET-SUM pos tot :计算当前数列的第pos个数字来说的连续的tot个数字的和并输出 //6:MAX-SUM :求出当前数列中和最大的一段序列,输出最大和 #include<bits/stdc++.h> #define Key_value ch[ch[root][1]][0] #define N 500005 #define INF 0x3f3f3f3f using namespace std; int n,m,a[N]; char s[20]; int pre[N],ch[N][2],key[N],size[N]; int root,tot1,tot2,st[N]; int sum[N],rev[N],same[N]; int lx[N],rx[N],mx[N]; //debug部分********************************** void Treavel(int x) { if(!x) return; Treavel(ch[x][0]); printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d\n",x,ch[x][0],ch[x][1],pre[x],size[x]); Treavel(ch[x][1]); } void debug() { printf("root:%d\n",root); Treavel(root); } //以上是debug部分************************************** void NewNode(int &r,int father,int k) { if(tot2) r = st[tot2--];//取的时候是tot2--,存的时候就是++tot2 else r = ++tot1; pre[r] = father; ch[r][0] = ch[r][1] = 0; key[r] = k; sum[r] = k; rev[r] = same[r] = 0; lx[r] = rx[r] = mx[r] = k; size[r] = 1; } void Update_Rev(int r) { if(!r)return; swap(ch[r][0],ch[r][1]); swap(lx[r],rx[r]); rev[r] ^= 1; } void Update_Same(int r,int v) { if(!r)return; key[r] = v; sum[r] = v*size[r]; lx[r] = rx[r] = mx[r] = max(v,v*size[r]); same[r] = 1; } void push_up(int r) { int lson = ch[r][0], rson = ch[r][1]; size[r] = size[lson]+size[rson]+1; sum[r] = sum[lson]+sum[rson]+key[r]; lx[r] = max(lx[lson],sum[lson]+key[r]+max(0,lx[rson])); rx[r] = max(rx[rson],sum[rson]+key[r]+max(0,rx[lson])); mx[r] = max(0,rx[lson])+key[r]+max(0,lx[rson]); mx[r] = max(mx[r],max(mx[lson],mx[rson])); } void push_down(int r) { if(same[r]) { Update_Same(ch[r][0],key[r]); Update_Same(ch[r][1],key[r]); same[r] = 0; } if(rev[r]) { Update_Rev(ch[r][0]); Update_Rev(ch[r][1]); rev[r] = 0; } } void Build(int &x,int l,int r,int father) { if(l > r) return; int mid = (l+r)/2; NewNode(x,father,a[mid]); Build(ch[x][0],l,mid-1,x); Build(ch[x][1],mid+1,r,x); push_up(x); } void Init() { root = tot1 = tot2 = 0; ch[root][0] = ch[root][1] = size[root] = pre[root] = 0; same[root] = rev[root] = sum[root] = key[root] = 0; lx[root] = rx[root] = mx[root] = -INF; NewNode(root,0,-1); NewNode(ch[root][1],root,-1); for(int i = 0;i < n;i++) scanf("%d",&a[i]); Build(Key_value,0,n-1,ch[root][1]); push_up(ch[root][1]); push_up(root); } //旋转,0为左旋,1为右旋 void Rotate(int x,int kind) { int y = pre[x]; push_down(y); push_down(x); ch[y][!kind] = ch[x][kind]; pre[ch[x][kind]] = y; if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y] = x; pre[x] = pre[y]; ch[x][kind] = y; pre[y] = x; push_up(y); } //Splay调整,将r结点调整到goal下面 void Splay(int r,int goal) { push_down(r); while(pre[r] != goal) { if(pre[pre[r]] == goal) { push_down(pre[r]); push_down(r); Rotate(r,ch[pre[r]][0] == r); } else { push_down(pre[pre[r]]); push_down(pre[r]); push_down(r); int y = pre[r]; int kind = ch[pre[y]][0]==y; if(ch[y][kind] == r) { Rotate(r,!kind); Rotate(r,kind); } else { Rotate(y,kind); Rotate(r,kind); } } } push_up(r); if(goal == 0) root = r; } int Get_kth(int r,int k) { push_down(r); int t = size[ch[r][0]] + 1; if(t == k) return r; if(t > k) return Get_kth(ch[r][0],k); else return Get_kth(ch[r][1],k-t); } //在第pos个数后面插入tot个数 void Insert(int pos,int tot) { for(int i = 0;i < tot;i++)scanf("%d",&a[i]); Splay(Get_kth(root,pos+1),0); Splay(Get_kth(root,pos+2),root); Build(Key_value,0,tot-1,ch[root][1]); push_up(ch[root][1]); push_up(root); } //删除子树 void erase(int r) { if(!r)return; st[++tot2] = r; erase(ch[r][0]); erase(ch[r][1]); } //从第pos个数开始连续删除tot个数 void Delete(int pos,int tot) { Splay(Get_kth(root,pos),0); Splay(Get_kth(root,pos+tot+1),root); erase(Key_value); pre[Key_value] = 0; Key_value = 0; push_up(ch[root][1]); push_up(root); } //将从第pos个数开始的连续的tot个数修改为c void Make_Same(int pos,int tot,int c) { Splay(Get_kth(root,pos),0); Splay(Get_kth(root,pos+tot+1),root); Update_Same(Key_value,c); push_up(ch[root][1]); push_up(root); } //将第pos个数开始的连续tot个数进行反转 void Reverse(int pos,int tot) { Splay(Get_kth(root,pos),0); Splay(Get_kth(root,pos+tot+1),root); Update_Rev(Key_value); push_up(ch[root][1]); push_up(root); } //得到第pos个数开始的tot个数的和 int Get_Sum(int pos,int tot) { Splay(Get_kth(root,pos),0); Splay(Get_kth(root,pos+tot+1),root); return sum[Key_value]; } //得到第pos个数开始的tot个数中最大的子段和 int Get_MaxSum(int pos,int tot) { Splay(Get_kth(root,pos),0); Splay(Get_kth(root,pos+tot+1),root); return mx[Key_value]; } void InOrder(int r) { if(!r) return; push_down(r); InOrder(ch[r][0]); printf("%d ",key[r]); InOrder(ch[r][1]); } int main() { scanf("%d%d",&n,&m); Init(); int x,y,z; while(m--) { scanf("%s",s); if(strcmp(s,"INSERT") == 0) { scanf("%d%d",&x,&y); Insert(x,y); } else if(strcmp(s,"DELETE") == 0) { scanf("%d%d",&x,&y); Delete(x,y); } else if(strcmp(s,"MAKE-SAME") == 0) { scanf("%d%d%d",&x,&y,&z); Make_Same(x,y,z); } else if(strcmp(s,"REVERSE") == 0) { scanf("%d%d",&x,&y); Reverse(x,y); } else if(strcmp(s,"GET-SUM") == 0) { scanf("%d%d",&x,&y); printf("%d\n",Get_Sum(x,y)); } else if(strcmp(s,"MAX-SUM") == 0) printf("%d\n",Get_MaxSum(1,size[root]-2)); } return 0; }
//动态维护一组森林,要求支持一下操作: //link(a,b) : 如果a,b不在同一颗子树中,则通过在a,b之间连边的方式,连接这两颗子树 //cut(a,b) : 如果a,b在同一颗子树中,且a!=b,则将a视为这颗子树的根以后,切断b与其父亲结点的连接 //ADD(a,b,w): 如果a,b在同一颗子树中,则将a,b之间路径上所有点的点权增加w //query(a,b): 如果a,b在同一颗子树中,返回a,b之间路径上点权的最大值 #include<bits/stdc++.h> #define N 300005 using namespace std; int n,q,op; int ch[N][2],pre[N],key[N]; int add[N],rev[N],Max[N]; bool rt[N]; vector<int> v[N]; void Update_Add(int r,int d) { if(!r)return; key[r] += d; add[r] += d; Max[r] += d; } void Update_Rev(int r) { if(!r)return; swap(ch[r][0],ch[r][1]); rev[r] ^= 1; } void push_down(int r) { if(add[r]) { Update_Add(ch[r][0],add[r]); Update_Add(ch[r][1],add[r]); add[r] = 0; } if(rev[r]) { Update_Rev(ch[r][0]); Update_Rev(ch[r][1]); rev[r] = 0; } } void push_up(int r) { Max[r] = max(max(Max[ch[r][0]],Max[ch[r][1]]),key[r]); } void Rotate(int x) { int y = pre[x], kind = ch[y][1] == x; ch[y][kind] = ch[x][!kind]; pre[ch[y][kind]] = y; pre[x] = pre[y]; pre[y] = x; ch[x][!kind] = y; if(rt[y]) { rt[y] = 0; rt[x] = 1; } else ch[pre[x]][ch[pre[x]][1]==y] = x; push_up(y); } //P函数先将根结点到r的路径上所有的结点的标记逐级下放 void P(int r) { if(!rt[r]) P(pre[r]); push_down(r); } void Splay(int r) { P(r); while(!rt[r]) { int f = pre[r],ff = pre[f]; if(rt[f]) Rotate(r); else if((ch[ff][1] == f) == (ch[f][1] == r)) { Rotate(f); Rotate(r); } else { Rotate(r); Rotate(r); } } push_up(r); } int Access(int x) { int y = 0; for(;x;x = pre[y = x]) { Splay(x); rt[ch[x][1]] = 1; rt[ch[x][1]=y] = 0; push_up(x); } return y; } //判断是否是同根(真实的树,非splay) bool judge(int u,int v) { while(pre[u]) u = pre[u]; while(pre[v]) v = pre[v]; return u == v; } //使r成为它所在的树的根 void mroot(int r) { Access(r); Splay(r); Update_Rev(r); } //调用后u是原来u和v的lca,v和ch[u][1]分别存着lca的2个儿子 //(原来u和v所在的2颗子树) void lca(int &u,int &v) { Access(v),v = 0; while(u) { Splay(u); if(!pre[u]) return; rt[ch[u][1]] = 1; rt[ch[u][1] = v] = 0; push_up(u); u = pre[v = u]; } } void link(int u,int v) { if(judge(u,v)) { puts("-1"); return; } mroot(u); pre[u] = v; } //使u成为u所在树的根,并且v和它父亲的边断开 void cut(int u,int v) { if(u == v || !judge(u,v)) { puts("-1"); return; } mroot(u); Splay(v); pre[ch[v][0]] = pre[v]; pre[v] = 0; rt[ch[v][0]] = 1; ch[v][0] = 0; push_up(v); } void ADD(int u,int v,int w) { if(!judge(u,v)) { puts("-1"); return; } lca(u,v); Update_Add(ch[u][1],w); Update_Add(v,w); key[u] += w; push_up(u); } void query(int u,int v) { if(!judge(u,v)) { puts("-1"); return; } lca(u,v); printf("%d\n",max(max(Max[v],Max[ch[u][1]]),key[u])); } void init() { for(int i = 1;i <= n;i++) v[i].clear(); for(int i = 0;i <= n;i++) { pre[i] = 0; ch[i][0] = ch[i][1] = 0; rev[i] = 0; add[i] = 0; rt[i] = 1; } Max[0] = -2000000000; } void dfs(int u) { for(int i = 0;i < v[u].size();i++) { int t = v[u][i]; if(pre[t] != 0)continue; pre[t] = u; dfs(t); } } int main() { while(~scanf("%d",&n)) { init(); for(int i = 1;i < n;i++) { int x,y; scanf("%d%d",&x,&y); v[x].push_back(y); v[y].push_back(x); } for(int i = 1;i <= n;i++) { scanf("%d",&key[i]); Max[i] = key[i]; } scanf("%d",&q); pre[1] = -1; dfs(1); pre[1] = 0; while(q--) { scanf("%d",&op); if(op == 1) { int x,y; scanf("%d%d",&x,&y); link(x,y); } else if(op == 2) { int x,y; scanf("%d%d",&x,&y); cut(x,y); } else if(op == 3) { int w,x,y; scanf("%d%d%d",&w,&x,&y); ADD(x,y,w); } else { int x,y; scanf("%d%d",&x,&y); query(x,y); } } printf("\n"); } return 0; }
主席树:
int n,q,m,tot,a[N],b[N]; int tree[N],lson[N*30],rson[N*30],c[N*30]; void init_hash() { for(int i = 1;i <= n;i++) b[i]=a[i]; sort(b+1,b+n+1); m = unique(b+1,b+n+1)-b-1; } int gethash(int x) { return lower_bound(b+1,b+1+m,x)-b; } void build(int &now,int l,int r) { now = tot++; c[now] = 0; if(l == r) return; int mid = (l+r)/2; build(lson[now],l,mid); build(rson[now],mid+1,r); } void update(int &now,int last,int l,int r,int pos,int x) { now = tot++; lson[now] = lson[last]; rson[now] = rson[last]; c[now] = c[last]+x; if(l == r) return; int mid = (l+r)/2; if(pos <= mid) update(lson[now],lson[last],l,mid,pos,x); else update(rson[now],rson[last],mid+1,r,pos,x); } int query(int lt,int rt,int l,int r,int k) { if(l == r) return l; int mid = (l+r)/2; if(c[lson[rt]]-c[lson[lt]] >= k) return query(lson[lt],lson[rt],l,mid,k); return query(rson[lt],rson[rt],mid+1,r,k-c[lson[rt]]+c[lson[lt]]); } int main() { ios::sync_with_stdio(0); while(~scanf("%d%d",&n,&q)) { for(int i = 1;i <= n;i++) scanf("%d",&a[i]); init_hash(); tot = 0; build(tree[0],1,m); for(int i = 1;i <= n;i++) update(tree[i],tree[i-1],1,m,gethash(a[i]),1); while(q--) { int l,r,k; scanf("%d%d%d",&l,&r,&k); printf("%d\n",b[query(tree[l-1],tree[r],1,m,k)]); } } return 0; }
int n,q,m,tot,a[N],b[N]; int tree[N],lson[N*100],rson[N*100],c[N*100]; map<int,int> mp; int build(int l,int r) { int now = tot++; c[now] = 0; if(l == r) return now; int mid = (l+r)/2; lson[now] = build(l,mid); rson[now] = build(mid+1,r); return now; } int update(int last,int pos,int x) { int now = tot++,t = now; c[now] = c[last]+x; int l = 1,r = n; while(l < r) { int mid = (l+r)/2; if(pos <= mid) { lson[now] = tot++; rson[now] = rson[last]; now = lson[now]; last = lson[last]; r = mid; } else { rson[now] = tot++; lson[now] = lson[last]; now = rson[now]; last = rson[last]; l = mid+1; } c[now] = c[last]+x; } return t; } int query(int pos,int now,int l,int r) { if(l == r) return c[now]; int mid = (l+r)/2; if(pos <= mid) return query(pos,lson[now],l,mid)+c[rson[now]]; return query(pos,rson[now],mid+1,r); } int main() { while(~scanf("%d",&n)) { for(int i = 1;i <= n;i++) scanf("%d",&a[i]); tot = 0; tree[0] = build(1,n); for(int i = 1;i <= n;i++) { if(mp.find(a[i]) == mp.end()) tree[i] = update(tree[i-1],i,1); else { int t = update(tree[i-1],mp[a[i]],-1); tree[i] = update(t,i,1); } mp[a[i]] = i; } scanf("%d",&q); while(q--) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",query(l,tree[r],1,n)); } } return 0; }
int n,q,m,tot,cnt,a[N],b[N],p[N],f[N*2],rmq[N*2]; int tree[N],lson[N*40],rson[N*40],c[N*40]; vector<int> v[N]; struct ST { int mm[2*N],dp[2*N][20]; void init(int n) { mm[0] = -1; for(int i = 1;i <= n;i++) { mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1]; dp[i][0] = i; } for(int j = 1;j <= mm[n];j++) { for(int i = 1;i+(1<<j)-1 <= n;i++) dp[i][j] = rmq[dp[i][j-1]] < rmq[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1]; } } int query(int a,int b) { if(a > b) swap(a,b); int k = mm[b-a+1]; return rmq[dp[a][k]] <= rmq[dp[b-(1<<k)+1][k]]?dp[a][k]:dp[b-(1<<k)+1][k]; } }st; void inithash() { for(int i = 1;i <= n;i++) b[i] = a[i]; sort(b+1,b+1+n); m = unique(b+1,b+1+n)-b-1; } int gethash(int x) { return lower_bound(b+1,b+1+m,x)-b; } void dfs(int now,int pre,int dep) { f[++cnt] = now; rmq[cnt] = dep; p[now] = cnt; for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; dfs(t,now,dep+1); f[++cnt] = now; rmq[cnt] = dep; } } void initlca(int root,int n) { cnt = 0; dfs(root,root,0); st.init(2*n-1); } int querylca(int x,int y) { return f[st.query(p[x],p[y])]; } int build(int l,int r) { int now = tot++; c[now] = 0; if(l == r) return now; int mid = (l+r)/2; lson[now] = build(l,mid); rson[now] = build(mid+1,r); return now; } int update(int last,int pos,int x) { int now = tot++,t = now; c[now] = c[last]+x; int l = 1,r = m; while(l < r) { int mid = (l+r)/2; if(pos <= mid) { lson[now] = tot++; rson[now] = rson[last]; now = lson[now]; last = lson[last]; r = mid; } else { rson[now] = tot++; lson[now] = lson[last]; now = rson[now]; last = rson[last]; l = mid+1; } c[now] = c[last]+x; } return t; } void dfsbuild(int now,int pre) { tree[now] = update(tree[pre],gethash(a[now]),1); for(int i = 0;i < v[now].size();i++) { int t = v[now][i]; if(t == pre) continue; dfsbuild(t,now); } } int query(int lt,int rt,int lcat,int pos,int k,int l,int r) { if(l == r) return l; int mid = (l+r)/2; int t = c[lson[lt]]+c[lson[rt]]-2*c[lson[lcat]]; if(pos >= l && pos <= mid) t++; if(t >= k) return query(lson[lt],lson[rt],lson[lcat],pos,k,l,mid); return query(rson[lt],rson[rt],rson[lcat],pos,k-t,mid+1,r); } int main() { scanf("%d%d",&n,&q); for(int i = 1;i <= n;i++) scanf("%d",&a[i]); inithash(); tot = 0; for(int i = 1;i < n;i++) { int x,y; scanf("%d%d",&x,&y); v[x].push_back(y); v[y].push_back(x); } initlca(1,n); tree[0] = build(1,m); dfsbuild(1,0); while(q--) { int x,y,k; scanf("%d%d%d",&x,&y,&k); int t = querylca(x,y); printf("%d\n",b[query(tree[x],tree[y],tree[t],gethash(a[t]),k,1,m)]); } return 0; }
int n,q,m,tot,a[N],b[N],use[N];; int tree[N],tree2[N],lson[N*50],rson[N*50],c[N*50]; struct Query { int kind; int l,r,k; }query[10010]; void Init_hash(int k) { sort(b,b+k); m = unique(b,b+k) - b; } int hash(int x) { return lower_bound(b,b+m,x)-b; } int build(int l,int r) { int root = tot++; c[root] = 0; if(l != r) { int mid = (l+r)/2; lson[root] = build(l,mid); rson[root] = build(mid+1,r); } return root; } int Insert(int root,int pos,int val) { int newroot = tot++, tmp = newroot; int l = 0, r = m-1; c[newroot] = c[root] + val; while(l < r) { int mid = (l+r)>>1; if(pos <= mid) { lson[newroot] = tot++; rson[newroot] = rson[root]; newroot = lson[newroot]; root = lson[root]; r = mid; } else { rson[newroot] = tot++; lson[newroot] = lson[root]; newroot = rson[newroot]; root = rson[root]; l = mid+1; } c[newroot] = c[root] + val; } return tmp; } int lowbit(int x) { return x&(-x); } void add(int x,int pos,int val) { while(x <= n) { tree2[x] = Insert(tree2[x],pos,val); x += lowbit(x); } } int sum(int x) { int ret = 0; while(x > 0) { ret += c[lson[use[x]]]; x -= lowbit(x); } return ret; } int Query(int left,int right,int k) { int left_root = tree[left-1]; int right_root = tree[right]; int l = 0, r = m-1; for(int i = left-1;i;i -= lowbit(i)) use[i] = tree2[i]; for(int i = right;i ;i -= lowbit(i)) use[i] = tree2[i]; while(l < r) { int mid = (l+r)/2; int tmp = sum(right) - sum(left-1) + c[lson[right_root]] - c[lson[left_root]]; if(tmp >= k) { r = mid; for(int i = left-1; i ;i -= lowbit(i)) use[i] = lson[use[i]]; for(int i = right; i; i -= lowbit(i)) use[i] = lson[use[i]]; left_root = lson[left_root]; right_root = lson[right_root]; } else { l = mid+1; k -= tmp; for(int i = left-1; i;i -= lowbit(i)) use[i] = rson[use[i]]; for(int i = right;i ;i -= lowbit(i)) use[i] = rson[use[i]]; left_root = rson[left_root]; right_root = rson[right_root]; } } return l; } void Modify(int x,int p,int d) { while(x <= n) { tree2[x] = Insert(tree2[x],p,d); x += lowbit(x); } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&q); tot = 0; m = 0; for(int i = 1;i <= n;i++) { scanf("%d",&a[i]); b[m++] = a[i]; } char op[10]; for(int i = 0;i < q;i++) { scanf("%s",op); if(op[0] == 'Q') { query[i].kind = 0; scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].k); } else { query[i].kind = 1; scanf("%d%d",&query[i].l,&query[i].r); b[m++] = query[i].r; } } Init_hash(m); tree[0] = build(0,m-1); for(int i = 1;i <= n;i++) tree[i] = Insert(tree[i-1],hash(a[i]),1); for(int i = 1;i <= n;i++) tree2[i] = tree[0]; for(int i = 0;i < q;i++) { if(query[i].kind == 0) printf("%d\n",b[Query(query[i].l,query[i].r,query[i].k)]); else { Modify(query[i].l,hash(a[query[i].l]),-1); Modify(query[i].l,hash(query[i].r),1); a[query[i].l] = query[i].r; } } } return 0; }