bzoj 3531 旅行

动态开点线段树+树链剖分  对于每一种宗教信仰都开一颗线段树

  空间: QlogN 即每一次修改都只会改变logN 个点

  时间 O(QlogN)  naive题  边没有开两倍  QAQ

bzoj 3531
  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 inline int read()
  5 {
  6     int x=0,f=1;
  7     char ch=getchar();
  8     while(ch<'0'||ch>'9')
  9     {
 10         if(ch=='-')f=-1;
 11         ch=getchar();
 12     }
 13     while(ch>='0'&&ch<='9')
 14     {
 15         x=x*10+ch-'0';
 16         ch=getchar();
 17     }
 18     return x*f;
 19 }
 20 int ee=0,st[300010],fa[300010],top[300010],son[300010],lastadd;
 21 int n,q,belif[300010],weight[300010],size[300010],dep[300010],cnt,pl[300010];
 22 struct edge
 23 {
 24     int v,next;
 25 } vs[300010];
 26 inline void addedge(int u,int v)
 27 {
 28     vs[++ee].v=v;
 29     vs[ee].next=st[u];
 30     st[u]=ee;
 31 }
 32 struct treenode
 33 {
 34     int l,r,mx,sum;
 35 } tree[30000010];
 36 treenode operator+(treenode a,treenode b)
 37 {
 38     treenode tmp;
 39     tmp.sum=a.sum+b.sum;
 40     tmp.mx=max(a.mx,b.mx);
 41     return tmp;
 42 }
 43 void modify(int q,int x,int l,int r,int rt)
 44 {
 45     if(l==r)
 46     {
 47         tree[rt].mx=x;
 48         tree[rt].sum=x;
 49         return ;
 50     }
 51     int mid=(l+r)>>1;
 52     if(mid>=q)
 53     {
 54         if(!tree[rt].l) tree[rt].l=++cnt;
 55         modify(q,x,l,mid,tree[rt].l);
 56     }
 57     if(mid<q)
 58     {
 59         if(!tree[rt].r) tree[rt].r=++cnt;
 60         modify(q,x,mid+1,r,tree[rt].r);
 61     }
 62     tree[rt].sum=tree[tree[rt].l].sum+tree[tree[rt].r].sum;
 63     tree[rt].mx=max(tree[tree[rt].l].mx,tree[tree[rt].r].mx);
 64 }
 65 treenode query(int L,int R,int l,int r,int rt)
 66 {
 67     if(L<=l&&r<=R) return tree[rt];
 68     int mid=(l+r)>>1;
 69     if(mid>=R) return query(L,R,l,mid,tree[rt].l);
 70     if(mid<L) return query(L,R,mid+1,r,tree[rt].r);
 71     return query(L,R,l,mid,tree[rt].l)+query(L,R,mid+1,r,tree[rt].r);
 72 }
 73 void dfs1(int rt)
 74 {
 75     size[rt]=1;
 76     for(int i=st[rt]; i; i=vs[i].next)
 77     {
 78         if(fa[rt]==vs[i].v) continue;
 79         fa[vs[i].v]=rt;
 80         dep[vs[i].v]=dep[rt]+1;
 81         dfs1(vs[i].v);
 82         size[rt]+=size[vs[i].v];
 83         if(size[son[rt]]<size[vs[i].v])
 84             son[rt]=vs[i].v;
 85     }
 86 }
 87 void dfs2(int rt)
 88 {
 89     pl[rt]=++lastadd;
 90     if(son[rt])
 91     {
 92         top[son[rt]]=top[rt];
 93         dfs2(son[rt]);
 94     }
 95     for(int i=st[rt]; i; i=vs[i].next)
 96     {
 97         if(vs[i].v==fa[rt]||son[rt]==vs[i].v) continue;
 98         dfs2(vs[i].v);
 99     }
100 }
101 void op(int &a,treenode b,int tp)
102 {
103     if(tp==0) a=max(a,b.mx);
104     else a+=b.sum;
105 }
106 void calans(int x,int y,int tp)
107 {
108     int f1=top[x],f2=top[y];
109     if(dep[f1]>dep[f2])
110         swap(x,y),swap(f1,f2);
111     int ans=0,rt=belif[x];
112     while(f1!=f2)
113     {
114         treenode tt=query(pl[f2],pl[y],1,n,rt);
115         op(ans,tt,tp);
116         y=fa[f2];
117         f2=top[y];
118         if(dep[f1]>dep[f2]) swap(f1,f2),swap(x,y);
119     }
120     if(dep[x]>dep[y]) swap(x,y);
121     treenode tt=query(pl[x],pl[y],1,n,rt);
122     op(ans,tt,tp);
123     printf("%d\n",ans);
124 }
125 void cgbelif(int x,int y)
126 {
127     modify(pl[x],0,1,n,belif[x]);
128     belif[x]=y;
129     modify(pl[x],weight[x],1,n,belif[x]);
130 }
131 void cgwight(int x,int y)
132 {
133     modify(pl[x],weight[x]=y,1,n,belif[x]);
134 }
135 int main()
136 {
137     cnt=100010;
138     n=read();
139     q=read();
140     for(int i=1; i<=n; i++)
141         top[i]=i;
142     for(int i=1; i<=n; i++)
143     {
144         weight[i]=read();
145         belif[i]=read();
146     }
147     for(int i=1; i<n; i++)
148     {
149         int a=read(),b=read();
150         addedge(a,b);
151         addedge(b,a);
152     }
153     dfs1(1);
154     dfs2(1);
155     for(int i=1; i<=n; i++)
156         modify(pl[i],weight[i],1,n,belif[i]);
157     for(int i=1; i<=q; i++)
158     {
159         char sd[10];
160         scanf("%s",sd);
161         int x=read(),y=read();
162         if(sd[0]=='Q')
163         {
164             if(sd[1]=='M') calans(x,y,0);
165             else calans(x,y,1);
166         }
167         else if(sd[0]=='C')
168         {
169             if(sd[1]=='C') cgbelif(x,y);
170             else cgwight(x,y);
171         }
172     }
173     return 0;
174 }
View Code

 

蛤鸡附上 dmk

dmk_GG  好像有点问题QWQ
 1 #include <bits/stdc++.h>
 2 #define N 30010
 3 #define Q 30010
 4 #define C 1000
 5 using namespace std;
 6 
 7 int bf[N+10],wt[N+10],sign[N+10];
 8 vector <int> xx[N+10];
 9 char ch[4][3]= {{'Q','S','\0'},{'Q','S','\0'},{'C','C','\0'},{'C','W','\0'}};
10 int main()
11 {
12     srand(time(0));
13     freopen("read.in","w",stdout);
14     printf("%d %d\n",N,Q);
15     for(int i=1; i<=N; i++)
16     {
17         bf[i]=rand()%C+1;
18         xx[bf[i]].push_back(i);
19         wt[i]=rand()%10000;
20     }
21     for(int i=1; i<=N; i++)
22         printf("%d %d\n",wt[i],bf[i]);
23     sign[1]=1;
24     sign[2]=1;
25     printf("%d %d\n",1,2);
26     for(int i=1; i<N-1; i++)
27     {
28         int x=rand()%N+1,y=rand()%N+1;
29         while(!sign[x]) x=rand()%N+1;
30         while(sign[y]) y=rand()%N+1;
31         printf("%d %d\n",x,y);
32         sign[y]=1;
33     }
34     for(int i=1; i<=Q; i++)
35     {
36         int ty=rand()%4;
37         puts(ch[ty]);
38         if(ty==2||ty==3)
39         {
40             int x=rand()%N+1,y=rand()%C+1;
41             printf("%d %d\n",x,y);
42             if(ty==2)
43             {
44                 for(int j=0; j<=(int)xx[bf[x]].size(); j++)
45                     if(xx[bf[x]][j]==x)
46                         xx[bf[x]].erase(xx[bf[x]].begin()+j);
47                 bf[x]=y;
48             }
49 
50         }
51         if(ty==0||ty==1)
52         {
53             int x=rand()%N+1;
54             while(xx[bf[x]].size()==1)
55                 x=rand()%N+1;
56             printf("%d %d\n",x,xx[bf[x]][rand()%xx[bf[x]].size()]);
57         }
58     }
59     return 0;
60 }
View Code

 

posted @ 2017-01-06 16:07  蛤鸡  阅读(158)  评论(0编辑  收藏  举报