ctsc前例行砍手
可并堆、并查集 zoj2334
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> #include <vector> #include <math.h> #include <limits> #include <set> #include <map> using namespace std; #define SZ 666666 int ch[SZ][2],dis[SZ],v[SZ]; int merge(int a,int b) { if(!a||!b) return a+b; if(v[a]<v[b]) swap(a,b); ch[a][1]=merge(ch[a][1],b); if(dis[ch[a][0]]<dis[ch[a][1]]) swap(ch[a][0],ch[a][1]); if(!ch[a][1]) dis[a]=0; else dis[a]=dis[ch[a][1]]+1; return a; } int pop(int a) { int t=merge(ch[a][0],ch[a][1]); ch[a][0]=ch[a][1]=dis[a]=0; return t; } int ff[SZ],rot[SZ]; int gf(int x) {return ff[x]?ff[x]=gf(ff[x]):x;} int n,m; void sol() { for(int i=1;i<=n;i++) scanf("%d",v+i), ch[i][0]=ch[i][1]=dis[i]=ff[i]=0, rot[i]=i; scanf("%d",&m); while(m--) { int a,b; scanf("%d%d",&a,&b); int ga=gf(a),gb=gf(b); if(ga==gb) {puts("-1"); continue;} v[rot[ga]]/=2; v[rot[gb]]/=2; int aa=merge(pop(rot[ga]),rot[ga]); int bb=merge(pop(rot[gb]),rot[gb]); rot[ga]=merge(aa,bb); ff[gb]=ga; printf("%d\n",v[rot[ga]]); } } int main() { while(scanf("%d",&n)!=-1) sol(); }
cdq分治 bzoj1176
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <algorithm> #include <string.h> #include <vector> #include <math.h> #include <limits> #include <set> #include <map> using namespace std; int s,w,q=0,Q=0,ans[233333]; //tp=0 edit //tp=1 query //op: -1/1 for query // value for edit struct cq {int x,y,op,tp,qid;}qs[233333]; bool operator < (cq a,cq b) {return a.x<b.x;} int bits[2333333]; int sum(int x) { int ans=0; for(;x>=1;x-=x&-x) ans+=bits[x]; return ans; } void edit(int x,int y) { for(;x<=w;x+=x&-x) bits[x]+=y; } void cdq(int l,int r) { if(l>=r) return; int mid=(l+r)>>1; cdq(l,mid); cdq(mid+1,r); sort(qs+l,qs+mid+1); sort(qs+mid+1,qs+r+1); int cur=l; for(int i=mid+1;i<=r;i++) { if(qs[i].tp!=1) continue; int x=qs[i].x; while(cur<=mid&&qs[cur].x<=x) { if(qs[cur].tp==0) edit(qs[cur].y,qs[cur].op); ++cur; } ans[qs[i].qid]+=qs[i].op*sum(qs[i].y); } for(int i=l;i<cur;i++) if(qs[i].tp==0) edit(qs[i].y,-qs[i].op); } int main() { scanf("%d%d",&s,&w); int o,a,b,c,d; while(1) { scanf("%d",&o); if(o==1) { scanf("%d%d%d",&a,&b,&c); ++q; qs[q].x=a; qs[q].y=b; qs[q].tp=0; qs[q].op=c; } else if(o==2) { scanf("%d%d%d%d",&a,&b,&c,&d); ++Q; ++q; qs[q].x=a-1; qs[q].y=b-1; qs[q].tp=1; qs[q].op=1; qs[q].qid=Q; ++q; qs[q].x=c; qs[q].y=b-1; qs[q].tp=1; qs[q].op=-1; qs[q].qid=Q; ++q; qs[q].x=a-1; qs[q].y=d; qs[q].tp=1; qs[q].op=-1; qs[q].qid=Q; ++q; qs[q].x=c; qs[q].y=d; qs[q].tp=1; qs[q].op=1; qs[q].qid=Q; } else break; } cdq(1,q); for(int i=1;i<=Q;i++) printf("%d\n",ans[i]); }
二维线段树 bzoj1176
时间: 2024-10-13 04:54:30