NOI前总结:点分治

点分治:

点分治的题目基本一样,都是路径计数。

其复杂度的保证是依靠 $O(n)$ 找重心的,每一次至少将问题规模减小为原先的$1/2$。

找重心我喜欢$BFS$防止爆栈。

 1 int Root(int x){
 2     dfsn[0]=0;
 3     q.push(x); fa[x]=0;
 4     flag[x]=1;
 5     while(!q.empty()){
 6         int x=q.front(); q.pop();
 7         dfsn[++dfsn[0]]=x;
 8         for(int i=g[x];i;i=E[i].to)
 9             if(!v[p] && !flag[p]){
10                 fa[p]=x;
11                 flag[p]=1;
12                 q.push(p);
13             }
14     }
15     for(int i=1;i<=dfsn[0];i++){
16         siz[dfsn[i]]=1;
17         h[dfsn[i]]=0;
18         flag[dfsn[i]]=0;
19     }
20     int root=0;
21     for(int i=dfsn[0];i>=1;i--){
22         int x=dfsn[i];
23         if(fa[x]){
24             siz[fa[x]]+=siz[x];
25             h[fa[x]]=max(h[fa[x]],siz[x]);
26         }
27         h[x]=max(h[x],dfsn[0]-siz[x]);
28         if(!root || h[x]<h[root]) root=x;
29     }
30     return root;
31 }

故总共有 $O(logn)$ 层。

在每一层我们分别对不同的块(删点而形成)采用 $O(siz[p])$ 的算法。

主定理 $T(n) = T(n/2) + O(n)$

总体上是 $O(nlogn)$

大体框架如下

 1 void DC(int x){
 2     v[x]=1;
 3     for(int i=g[x];i;i=E[i].to)
 4         if(!v[p]){
 5   //    大体上是f[x]*ft[x]就是
 6  //     Ans = (之前的子树的路径数)*(当前子树的路径数)
 7         }
 8   //    将标记什么的清空,注意保证复杂度是O(siz)不是O(n)
 9     for(int i=g[x];i;i=E[i].to)
10         if(!v[p]) DC(Root(p));
11 }    

然后对于点分治路径的统计,通常有dp,数据结构,数论等等的方法。

注意:要记得上面的方法没有统计以点x为起点的路径条数,记得加上。

例题:

BZOJ 3697

题意:

给出一棵树,每一条边为黑或白,统计满足条件的路径数

1.路径上黑色和白色的个数相等

2.路径上存在一个点使得起点到当前点黑色和白色的个数相等,此点不能是起点终点。

乍一看是没有解法的,套用点分治。

问题转化为统计过点x的合法路径条数。

套用dp

$f(x,0)$ 表示和为x,无休息站的

$f(x,1)$ 表示和为x,有休息站的

$$ans = f(0,0) * ft(0,0) + \sum_{i=-d}^d {f(i,0) \cdot ft(-i,1) + f(i,1) \cdot ft(-i,0) + f(i,1) \cdot ft(-i,1)} $$

条件2可以转化为在当前点到x的路径上有点的$dis(p) = dis(now)$

所以注意保证初始化的复杂度

所以记录一下当前的最大深度,初始化 $f$ 数组和 $ft$ 数组的时候从0循环到 $max deep$

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5
  6 #define N 400010
  7 #define p E[i].x
  8 #define LL long long
  9 #define debug(x) cout<<#x<<" = "<<x<<endl;
 10
 11 /*
 12 树形dp
 13 f(x,0) 表示和为x,无休息站的
 14 f(x,1) 表示和为x,有休息站的
 15 ans = f[0][0] * ft[0][0] +
 16     ∑ f[i][0]*ft[-i][1] + f[i][1]*ft[-i][0] + f[i][1]*ft[-i][1]
 17     (-d <= i <= d)
 18 */
 19
 20 using namespace std;
 21
 22 struct edge{
 23     int x,to,v;
 24 }E[N<<1];
 25
 26 int n,totE;
 27 int g[N],dfsn[N],fa[N],siz[N],h[N];
 28 bool v[N],flag[N];
 29 LL ans;
 30 LL f[N][2],ft[N][2];
 31 queue<int> q;
 32
 33 void ade(int x,int y,int v){
 34     E[++totE]=(edge){y,g[x],v}; g[x]=totE;
 35 }
 36
 37 int Root(int x){
 38     dfsn[0]=0;
 39     q.push(x); fa[x]=0;
 40     flag[x]=1;
 41     while(!q.empty()){
 42         int x=q.front(); q.pop();
 43         dfsn[++dfsn[0]]=x;
 44         for(int i=g[x];i;i=E[i].to)
 45             if(!v[p] && !flag[p]){
 46                 fa[p]=x;
 47                 flag[p]=1;
 48                 q.push(p);
 49             }
 50     }
 51     for(int i=1;i<=dfsn[0];i++){
 52         siz[dfsn[i]]=1;
 53         h[dfsn[i]]=0;
 54         flag[dfsn[i]]=0;
 55     }
 56     int root=0;
 57     for(int i=dfsn[0];i>=1;i--){
 58         int x=dfsn[i];
 59         if(fa[x]){
 60             siz[fa[x]]+=siz[x];
 61             h[fa[x]]=max(h[fa[x]],siz[x]);
 62         }
 63         h[x]=max(h[x],dfsn[0]-siz[x]);
 64         if(!root || h[x]<h[root]) root=x;
 65     }
 66     return root;
 67 }
 68
 69 int mxdep;
 70 int cnt[N],d[N],dis[N];
 71
 72 void dfs(int x,int fa){
 73     mxdep=max(mxdep,d[x]);
 74     if(cnt[dis[x]]) ft[dis[x]][1]++;
 75     else ft[dis[x]][0]++;
 76     cnt[dis[x]]++;
 77     for(int i=g[x];i;i=E[i].to)
 78         if(p!=fa&&!v[p]){
 79             d[p]=d[x]+1;
 80             dis[p]=dis[x]+E[i].v;
 81             dfs(p,x);
 82         }
 83     cnt[dis[x]]--;
 84 }
 85
 86 void DC(int x){
 87     v[x]=1;
 88     f[n][0]=1;
 89     int mx=0;
 90     for(int i=g[x];i;i=E[i].to)
 91         if(!v[p]){
 92             dis[p]=n+E[i].v;
 93             d[p]=mxdep=1;
 94             dfs(p,p);
 95             mx=max(mx,mxdep);
 96             ans+=(f[n][0]-1)*ft[n][0];
 97             for(int j=-mxdep;j<=mxdep;j++){
 98                 ans+=ft[n-j][1]*f[n+j][1]+
 99                     ft[n-j][0]*f[n+j][1]+ft[n-j][1]*f[n+j][0];
100             }
101             for(int j=n-mxdep;j<=n+mxdep;j++){
102                 f[j][0]+=ft[j][0];
103                 f[j][1]+=ft[j][1];
104                 ft[j][0]=ft[j][1]=0;
105             }
106         }
107     for(int i=n-mx;i<=n+mx;i++)
108         f[i][0]=f[i][1]=0;
109     for(int i=g[x];i;i=E[i].to)
110         if(!v[p]) DC(Root(p));
111 }
112
113
114 int main(){
115     scanf("%d",&n);
116     for(int i=1,x,y;i<n;i++){
117         int v;
118         scanf("%d%d%d",&x,&y,&v);
119         if(!v) v=-1;
120         ade(x,y,v); ade(y,x,v);
121     }
122     DC(Root(1));
123     printf("%lld\n",ans);
124     return 0;
125 }

然后是HDU 4812

题意:给出一棵树,每一个点有一个点权,找到一条点权乘积为K的路径,输出起点和终点,要求字典序最小。

求一下逆元,然后用map记录前面的所有子树能够到达的权值(乘积)

注意这是点权,不同于边权,所以在处理过点x的路径的时候要谨慎,我的做法是将路径拆为 x点 , 之前子树中的一条链, 当前子树中的一条链。

用map复杂度多一个log,然而也能过。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <map>
  5 #include <queue>
  6
  7 #define N 400010
  8 #define LL long long
  9 #define mod 1000003
 10 #define p E[i].x
 11 #define INF 0x3f3f3f3f
 12 #define ipos map<int,int>::iterator
 13
 14 using namespace std;
 15
 16 struct edge{
 17     int x,to;
 18 }E[N<<1];
 19
 20 map<int,int> ft,f;
 21 int n,ansv[2],totE,K;
 22 int h[N],g[N],siz[N],a[N],fa[N],dfsn[N],dis[N];
 23 bool v[N],flag[N];
 24 queue<int> q;
 25
 26 int add(int a,int b){
 27     if(a+b>=mod) return a+b-mod;
 28     return a+b;
 29 }
 30
 31 int mul(int a,int b){
 32     return (int)((LL)a*(LL)b%mod);
 33 }
 34
 35 int qpow(int x,int n){
 36     int ans=1;
 37     for(;n;n>>=1,x=mul(x,x))
 38         if(n&1) ans=mul(ans,x);
 39     return ans;
 40 }
 41
 42 int inv(int x){
 43     return (int)qpow((LL)x,mod-2LL);
 44 }
 45
 46 void ade(int x,int y){
 47     E[++totE]=(edge){y,g[x]}; g[x]=totE;
 48 }
 49
 50 int Root(int x){
 51     dfsn[0]=0;
 52     q.push(x); fa[x]=0;
 53     flag[x]=1;
 54     while(!q.empty()){
 55         int x=q.front(); q.pop();
 56         dfsn[++dfsn[0]]=x;
 57         for(int i=g[x];i;i=E[i].to)
 58             if(!v[p] && !flag[p]){
 59                 fa[p]=x;
 60                 flag[p]=1;
 61                 q.push(p);
 62             }
 63     }
 64     for(int i=1;i<=dfsn[0];i++){
 65         siz[dfsn[i]]=1;
 66         h[dfsn[i]]=0;
 67         flag[dfsn[i]]=0;
 68     }
 69     int root=0;
 70     for(int i=dfsn[0];i>=1;i--){
 71         int x=dfsn[i];
 72         if(fa[x]){
 73             siz[fa[x]]+=siz[x];
 74             h[fa[x]]=max(h[fa[x]],siz[x]);
 75         }
 76         h[x]=max(h[x],dfsn[0]-siz[x]);
 77         if(!root || h[x]<h[root]) root=x;
 78     }
 79     return root;
 80 }
 81
 82 void bfs(int x){
 83     dfsn[0]=0;
 84     q.push(x); flag[x]=1;
 85     while(!q.empty()){
 86         int x=q.front(); q.pop();
 87         dfsn[++dfsn[0]]=x;
 88         if(!ft.count(dis[x]) || ft[dis[x]]>x)
 89             ft[dis[x]]=x;
 90         for(int i=g[x];i;i=E[i].to)
 91             if(!v[p] && !flag[p]){
 92                 flag[p]=1;
 93                 dis[p]=mul(dis[x],a[p]);
 94                 q.push(p);
 95             }
 96     }
 97     for(int i=1;i<=dfsn[0];i++)
 98         flag[dfsn[i]]=0;
 99 }
100
101 void upd(int a,int b){
102     if(a>b) swap(a,b);
103     if(ansv[0]>a || ansv[0]==a&&ansv[1]>b){
104         ansv[0]=a;
105         ansv[1]=b;
106     }
107 }
108
109 void DC(int x){
110 //    printf("node : %d\n",x);
111     v[x]=1;
112     f.clear();
113     f[1]=x;
114     for(int i=g[x];i;i=E[i].to)
115         if(!v[p]){
116             ft.clear();
117             dis[p]=a[p];
118             bfs(p);
119             for(ipos it=ft.begin();it!=ft.end();it++){
120                 int tmp=(*it).first;
121                 if(f.count(mul(mul(K,inv(tmp)),inv(a[x])))){
122                     upd(f[mul(mul(K,inv(tmp)),inv(a[x]))],
123                         (*it).second);
124                 }
125             }
126             for(ipos it=ft.begin();it!=ft.end();it++){
127                 if(!f.count((*it).first)) f[(*it).first]=(*it).second;
128                 else f[(*it).first]=min(f[(*it).first],(*it).second);
129             }
130         }
131     for(int i=g[x];i;i=E[i].to)
132         if(!v[p]) DC(Root(p));
133 }
134
135 int main(){
136 //    freopen("test.in","r",stdin);
137     while(scanf("%d%d",&n,&K)==2){
138         ansv[0]=ansv[1]=INF;
139         totE=0;
140         for(int i=1;i<=n;i++) g[i]=0;
141         for(int i=1;i<=n;i++) scanf("%d",&a[i]),v[i]=0;
142         for(int i=1,x,y;i<n;i++){
143             int v;
144             scanf("%d%d",&x,&y);
145             ade(x,y);
146             ade(y,x);
147         }
148         DC(Root(1));
149         if(ansv[0]==INF) puts("No solution");
150         else printf("%d %d\n",ansv[0],ansv[1]);
151     }
152     return 0;
153 }

最后是 国家集训队的 crash的文明世界

题意:

定义:

求所有点的S(i)

很显然是点分治,斯特林数是什么,我不会 TAT

记录$f(i)$表示$\sum {dist(p,x)^i }$,$ft$同理

考虑每一次统计过x的路径时将过x的路径的影响加入子树中的点,同时在最后将$S(i)$加上$f(K)$

坑点就是合并的时候要用一下 二项式展开

$$ S(p) += \sum_{i=0}^K {C(K,i) * f(K-i) * b^i}$$

然后注意要统计全路径,所以上面的框架不适用(上面的框架对于当前子树只能统计遍历过的子树,而应该是统计所有除了当前子树的权值和)

然后就可以了,自己歪歪(看不懂题解),一遍AC爽。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <queue>
  5
  6 #define N 200010
  7 #define mod 10007
  8 #define M 310
  9 #define p E[i].x
 10
 11 using namespace std;
 12 /*
 13 f[j] 之前的  dist(x,p)^j
 14 ft[j] 当前的 dist(x,p)^j
 15 S[p] += ∑C(K,i) * a^{K-i} * b^i  (0<=i<=K)
 16 O(lognK)
 17 */
 18
 19 int n,K,totE;
 20 int g[N],f[M],siz[N],h[N],fa[N],dfsn[N],S[N],d[N];
 21 int C[M][M];
 22 bool v[N],flag[N];
 23 queue<int> q;
 24
 25 int add(int a,int b){
 26     if(a+b>=mod) return a+b-mod;
 27     return a+b;
 28 }
 29
 30 int mul(int a,int b){
 31     return a*b%mod;
 32 }
 33
 34 struct edge{
 35     int x,to;
 36 }E[N<<1];
 37
 38 void ade(int x,int y){
 39     E[++totE]=(edge){y,g[x]}; g[x]=totE;
 40 }
 41
 42 int qpow(int x,int n){
 43     int ans=1;
 44     for(;n;n>>=1,x=mul(x,x))
 45         if(n&1) ans=mul(ans,x);
 46     return ans;
 47 }
 48
 49 int Root(int x){
 50     dfsn[0]=0;
 51     q.push(x); fa[x]=0;
 52     flag[x]=1;
 53     while(!q.empty()){
 54         int x=q.front(); q.pop();
 55         dfsn[++dfsn[0]]=x;
 56         for(int i=g[x];i;i=E[i].to)
 57             if(!v[p] && !flag[p]){
 58                 fa[p]=x;
 59                 flag[p]=1;
 60                 q.push(p);
 61             }
 62     }
 63     for(int i=1;i<=dfsn[0];i++){
 64         siz[dfsn[i]]=1;
 65         h[dfsn[i]]=0;
 66         flag[dfsn[i]]=0;
 67     }
 68     int root=0;
 69     for(int i=dfsn[0];i>=1;i--){
 70         int x=dfsn[i];
 71         if(fa[x]){
 72             siz[fa[x]]+=siz[x];
 73             h[fa[x]]=max(h[fa[x]],siz[x]);
 74         }
 75         h[x]=max(h[x],dfsn[0]-siz[x]);
 76         if(!root || h[x]<h[root]) root=x;
 77     }
 78     return root;
 79 }
 80
 81 void bfs(int x){
 82     dfsn[0]=0; d[x]=1;
 83     q.push(x); flag[x]=1;
 84     while(!q.empty()){
 85         int x=q.front(); q.pop();
 86         dfsn[++dfsn[0]]=x;
 87         for(int i=g[x];i;i=E[i].to)
 88             if(!v[p] && !flag[p]){
 89                 d[p]=d[x]+1;
 90                 flag[p]=1;
 91                 q.push(p);
 92             }
 93     }
 94     for(int i=1;i<=dfsn[0];i++){
 95         int tmp=1;
 96         for(int j=0;j<=K;j++){
 97             f[j]=add(f[j],tmp);
 98             tmp=mul(tmp,d[dfsn[i]]);
 99         }
100         flag[dfsn[i]]=0;
101     }
102 }
103
104 int power[M];
105
106 void solve(int rt){
107     dfsn[0]=0; d[rt]=1;
108     q.push(rt); flag[rt]=1;
109     while(!q.empty()){
110         int x=q.front(); q.pop();
111         dfsn[++dfsn[0]]=x;
112         for(int i=g[x];i;i=E[i].to)
113             if(!v[p] && !flag[p]){
114                 d[p]=d[x]+1;
115                 flag[p]=1;
116                 q.push(p);
117             }
118     }
119     for(int i=1;i<=dfsn[0];i++){
120         int tmp=1;
121         for(int j=0;j<=K;j++){
122             f[j]=(f[j]-tmp+mod)%mod;
123             tmp=mul(tmp,d[dfsn[i]]);
124         }
125     }
126 //    printf("son : %d\n",rt);
127 //    for(int i=0;i<=K;i++){
128 //        printf("%d%c",f[i],i==K?‘\n‘:‘ ‘);
129 //    }
130     for(int t=1;t<=dfsn[0];t++){
131         int x=dfsn[t];
132         flag[x]=0;
133         power[0]=1;
134         for(int i=1;i<=K;i++) power[i]=mul(power[i-1],d[x]);
135         for(int i=0;i<=K;i++){
136         //    printf("addto %d = %d\n",x,mul(C[K][i], mul(f[K-i],power[i])));
137             S[x] = add(S[x], mul(C[K][i], mul(f[K-i],power[i])));
138         }
139         S[x]=add(S[x],power[K]);
140     }
141 //    S[x]=add(S[x],power[K]);
142     for(int i=1;i<=dfsn[0];i++){
143         int tmp=1;
144         for(int j=0;j<=K;j++){
145             f[j]=add(f[j],tmp);
146             tmp=mul(tmp,d[dfsn[i]]);
147         }
148     }
149 }
150 //S[p] += ∑C(K,i) * a^{K-i} * b^i  (0<=i<=K)
151 void DC(int x){
152     v[x]=1;
153 //    printf("node : %d\n",x);
154 //    for(int i=1;i<=dfsn[0];i++)
155 //        printf("%d%c",dfsn[i],i==dfsn[0]?‘\n‘:‘ ‘);
156     for(int i=0;i<=K;i++) f[i]=0;
157     for(int i=g[x];i;i=E[i].to)
158         if(!v[p]) bfs(p);
159 //    printf("before\n");
160 //    for(int i=0;i<=K;i++) printf("%d%c",f[i],i==K?‘\n‘:‘ ‘);
161     for(int i=g[x];i;i=E[i].to)
162         if(!v[p]) solve(p);
163     S[x]=add(S[x],f[K]);
164 //    printf("base = %d\n",f[K]);
165     for(int i=g[x];i;i=E[i].to)
166         if(!v[p]) DC(Root(p));
167 }
168
169 int main(){
170     freopen("civilization.in","r",stdin);
171     freopen("civilization.out","w",stdout);
172     scanf("%d%d",&n,&K);
173     C[0][0]=1;
174     for(int i=1;i<=K;i++){
175         C[i][0]=1;
176         for(int j=1;j<=i;j++)
177             C[i][j]=add(C[i-1][j-1],C[i-1][j]);
178     }
179     int L,now,A,B,Q,tmp;
180     scanf("%d%d%d%d%d",&L,&now,&A,&B,&Q);
181     for(int i=1,x,y;i<n;i++){
182         now=(now*A+B)%Q;
183         tmp=(i<L)? i:L;
184         x=i-now%tmp;
185         y=i+1;
186         ade(x,y);
187         ade(y,x);
188     }
189     DC(Root(1));
190     for(int i=1;i<=n;i++){
191         printf("%d\n",S[i]);
192     }
193     return 0;
194 }

总结完了点分治,NOI必胜。

时间: 2024-12-18 04:34:31

NOI前总结:点分治的相关文章

NOI前总结:数论(素数部分)

说到素数不得不说素数判定算法. 其中极为经典的为Rabin Miller测试. 通过二次探测的方法,我们可以将其正确率上升到一个很高的高度. 二次探测的原理我还是不太懂,所以NOI前我暂时只是梳理一下这个算法的流程. 首先,我来介绍一些小Trick. $O(1)$的快速乘. 在一些卡常数而且爆long long的取余问题中我们常常要用到快速乘. 朴素的快速乘是$O(logn)$的,从而添加了不必要的复杂度. 在这里介绍$O(1)$的快速乘. 在 c++ 运算中,有的时候是会爆long long的

NOI前训练记录

从今年年初开始就没怎么碰oi,学了三个月文化课,然后就是省选到处跑(浪),进了省队后又去北京打(浪)了波(七)铁(天),回家后又生了一星期病,感觉自己noi凉透了... ctsc因为运气的原因有人放弃D3自己才拿到au,apio什么牌都没拿到,自己这么菜的主要原因可能还是没怎么做题吧,五个月不碰oi,已经连dfs都不会了,还有两个月就noi了,再不训练又要为JS丢脸了,自己拿不到au却占了个省队名额,而阿老师邀请赛冠军的水平却没进省队,感觉自己不珍惜这个省队名额真的是说不过去 本文就记录一下本人

写在退役前的一些话

#include <cstdio> using namespace std; int main(){ puts("转载请注明出处:http://www.cnblogs.com/wangyurzee7/"); puts("谢谢您的配合"); puts("by wangyurzee7"); return 0; } 还有25小时的OI生涯.是时候写点什么了.一直很喜欢写东西,然而受语文水平限制,总是写不出像别人一样令人满意的文字. 小学的时

NOI冲刺计划

省选过了,剩下大概是NOI冲刺了吧.中间还有一大堆诸如会考,CTSC,APIO等东西. 最近先不急着天天刷八中了吧,多在不同网站见一些题,然后再着重提高一下代码准确性.重点把DP这个板块多练习一下,八中找DP题确实需要一定技巧,但其他网站DP题会多一些. 经hja计划的提醒,类似于TopTree的一系列算法至今不太会,找个时间编一下还是可以的,至于NOI考不考那是另外一回事了. 在省选复习期间也发现数论板块,DP板块有遗忘,也需要补一补. 说点具体的吧:NOI前bzoj上600+50就行了,不需

THUSC2017 记

不写流水账了. 短爷签了好劲啊. 而我跟个sb一样,去写了点垃圾暴力就回来了. "考挂了自己弱,就是这样" 真的该努力了. 为了家人.为了教练.为了老邸.为了3班.为了二中,更重要的,为了自己. "THU,我不会放弃的" "自己选择的路,跪着也要走完" 这句话以前看来甚至有点搞笑,现在才发现,这句话真的是一碗热鸡汤. 受到了许多人的鼓励,很感动. "加油,加油,加油" NOI前的每次浪我都会记到这篇文章下,希望在NOI前这篇文

NOI2017游记

Day -1: THUSC后,下定决心好好学习,不过由于自制力太弱,还是没有忍住浪了几次. 老师把NOI前的天分为了4种:考试日.交流日.讲课日.自习日. 考试日是我被郭神短神妖神任神常神尹神龙神游神柴神聪神和20亿个蒟蒻们虐的日子,成功让我认清自己是个垃圾的事实. 老师选了51nod上一堆题分派给大家,然后在交流日里讲,分给我的题是2道码农题和一道水题,除了郭神的一道题太神了没做外,其他人的题我都做了. 讲课日是老师请了各种大佬来讲课,基本全程都是郭神与大佬谈笑风生,其他人懵逼,大佬一般都会说

省队集训 Day1 残缺的字符串

[题目大意] 双串带通配符匹配. $|S|, |T| \leq 5 * 10^5$ TL: 2s [题解] 参考bzoj 4503 可以设计如下函数 A[i] * B[i] * (A[i] - B[i])^2 如果有通配符,A[i] = 0,否则,A[i] = s[i] - 'a' + 1:B同理. 可以自行验证,这是一种很妙的设计. 然后就是卷积的事情了.大概做9次DFT. 可以用类似于MTT的技巧搞到4次,不会写. # include <math.h> # include <stdi

PKUSC2017 游记

退役之前,写点破事乐呵乐呵 省选滚大粗   报了PKU和THU的SC  果然THU直接审核不通过... 于是就来到了PKU   滚粗狗就又续命几天. Day1 上午考数学 喜闻乐见啥都不会 出来一对题发现我还做错了一道.. 噗不差那一道题的... 下午 一试 先水了水签到题 剩下一个 麻烦的字符串.  刚刚刚  咔咔咔2K的字符串模拟题1A了好评 哈哈哈哈 1h写了2T  人生赢家有木有 随后开始了翻车之旅 一道SB的树形DP怎么调都调不对(最后弃疗) 另一道题 看不懂 题面 垃圾有道有的词还搜

spoj cot: Count on a tree 主席树

10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are numbered from 1 to N.Each node has an integer weight. We will ask you to perform the following operation: u v k : ask for the kth minimum weight on the path