NOIP模拟27

两个机房又和在一起考试

开场看了看T1,感觉挺水的,过。

T2,这个式子有点奇怪,暂时没什么思路,过

T3,好像保留最后几位换个根处理一下就行了,过,先去打T1

于是T1大概打了0.5h,连暴力带正解带对拍,码完之后感觉挺稳的,就过了。去看T3。

T3换个根就没事了,但是我一开始状态设置的有问题,一拍就爆炸了。

调调调,调过了T3,拍上了,感觉很稳,就交了一下T3和T1,此时过了两个小时

去把T2的式子化简了一下,发现只与前面所有数的和有关,好像是个很简单的dp,就码出来了。

不太会打暴力,于是码了个dfs,拍上了,很稳。

然后我去上了个厕所

然后碰见了DeepinC

然后他问我:“你切了几个?”

然后我感觉不太对劲,他都用“切”了,说明。。。。。。他AK了?

然后我决定回答:3个这句话目的在于给DeepinC压力,使他不会过早颓废

出分了,T2T3都A了,T1爆炸了

T1.

  注意这题不保证b是有序的,需要自己手动sort,不这么干会变成20分,别问我怎么知道的。

  然而我打对拍时智障地认为输入保证有序,于是我将所有数生成了出来,然后sort了一遍,然后输出

  然后错失了人生第一个AK

T2.

  把式子化简了,考虑每个点的贡献就没了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int f[32][32][3005],t;
 4 int n,m,a[35][35],ans;
 5 int main(){
 6     scanf("%d",&t);
 7     while(t--){
 8         ans=0x7fffffff;
 9         memset(f,0x3f,sizeof(f));
10         scanf("%d%d",&n,&m);
11         for(int i=1;i<=n;i++)
12             for(int j=1;j<=m;j++)
13                 scanf("%d",&a[i][j]);
14         f[1][1][a[1][1]]=(n+m-2)*a[1][1]*a[1][1];
15         for(int i=1;i<=n;i++)
16             for(int j=1;j<=m;j++){
17                 if(i==1&&j==1)continue;
18                 for(int k=1;k<=(i+j)*30;k++){
19                     int sum=(n+m-2)*a[i][j]*a[i][j]-k*a[i][j]*2;
20                     int mi=min(f[i-1][j][k],f[i][j-1][k]);
21                     if(mi==0x3f3f3f3f)continue;
22                     mi+=sum;
23                     f[i][j][k+a[i][j]]=min(f[i][j][k+a[i][j]],mi);
24                     if(i==n&&j==m)ans=min(ans,f[i][j][k+a[i][j]]);
25                 }
26             }
27         printf("%d\n",ans);
28     }
29     return 0;
30 }
View Code

T3.

  换根dp,考虑每个数二进制最后4位,统计答案即可。

  注意m!=0时不能算自己到自己的贡献。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,fi[100005],ne[200005],to[200005],ans,dis[100005],w[200005],tot;
 4 int res[100005],sum[100005][16],siz[100005],ss[100005][16];
 5 inline void add(int x,int y,int z){
 6     ne[++tot]=fi[x];
 7     fi[x]=tot;
 8     to[tot]=y;
 9     w[tot]=z;
10 }
11 void dfs(int x,int fa){
12     siz[x]=1;ss[x][0]=1;
13     for(int i=fi[x];i;i=ne[i]){
14         int y=to[i];
15         if(y!=fa){
16             dis[y]=dis[x]+w[i];
17             ans+=dis[y]^m;
18             res[1]+=dis[y];
19             dfs(y,x);
20             siz[x]+=siz[y];
21             for(int j=0;j<=15;j++)
22                 ss[x][(j+w[i])&15]+=ss[y][j];
23         }
24     }
25 }
26 void dfs2(int x,int fa){
27     for(int i=fi[x];i;i=ne[i]){
28         int y=to[i];
29         if(y!=fa){
30             res[y]=res[x]+(n-2*siz[y])*w[i];
31             for(int j=0;j<=15;j++){
32                 sum[y][(j+w[i])&15]+=sum[x][j]-ss[y][(j-(w[i]&15)+16)&15];
33                 sum[y][j]+=ss[y][j];
34             }
35             dfs2(y,x);
36         }
37     }
38 }
39 int main(){
40     scanf("%d%d",&n,&m);
41     for(int i=1,x,y,z;i<n;i++)
42         scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
43     dfs(1,0);
44     printf("%d\n",ans);
45     for(int i=0;i<=15;i++)
46         sum[1][i]=ss[1][i];
47     dfs2(1,0);
48     for(int i=2;i<=n;i++){
49         sum[i][0]--;
50         for(int j=0;j<=15;j++)
51             res[i]=res[i]-j*sum[i][j]+(m^j)*sum[i][j];
52         printf("%d\n",res[i]);
53     }
54     return 0;
55 }
View Code

 

posted @ 2019-08-20 14:23  tdcp  阅读(348)  评论(11编辑  收藏  举报