2017-10-02清北模拟赛

P98
zhx
竞赛时间: ????年??月??日??:??-??:??
题目名称
a
b
c
名称
a
b
c
输入
a.in
b.in
c.in
输出
a.out
b.out
c.out
每个测试点时限
1s
1s
1s
内存限制
256MB
256MB
256MB
测试点数目
10
10
10
每个测试点分值
10
10
10
是否有部分



题目类型
传统
传统
传统
注意 事项 (请务必仔细阅读) (请务必仔细阅读) :
P98 zhxa
第 2 页 共 6 页


T1 a

【问题描述】
你是能看到第一题的 friends呢。
—— hja
世界上没有什么比卖的这 贵弹丸三还令人绝望事了,所以便么一道题。定义 𝑓(𝑥)为满足 (𝑎×𝑏)|𝑥的有序正整数对 (𝑎,𝑏)的个数。现在给定 𝑁,求 Σ𝑓(𝑖)𝑁𝑖=1
【输入格式】
一行个整数 𝑁。
【输出格式】
一行个整数代表答案 。
【样例输入】
6
【样例输出】
25
【数据范围与规定】
对于 30%的数据, 1≤𝑛≤100。
对于 60%的数据, 1≤𝑛≤1000。
对于 100%的数据, 1≤𝑛≤1011.
P98 zhxb
第 3 页 共6 页

 

 1 /*
 2 60 n^2做法,找规律发现,
 3 对于每一个f[i]= i的每个约数的因子总个数、
 4 处理处f[i]累加ans便可
 5 但是数组开大爆零了 
 6 */
 7 #include <cstdio>
 8 
 9 #define LL long long
10 inline void read(LL &x)
11 {
12     x=0; register char ch=getchar();
13     for(; ch>'9'||ch<'0'; ) ch=getchar();
14     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
15 }
16 const int N(1e8+5);
17 LL n,ans,tmp,cnt[N],num[N];
18 
19 int Presist()
20 {
21     freopen("a.in","r",stdin);
22     freopen("a.out","w",stdout);
23     read(n);
24     for(int i=1; i<=n; ++i)
25     {
26         for(int j=1; j<=i; ++j)
27             if(i%j==0) cnt[i]++,num[++tmp]=j;
28         for(int j=1; j<=tmp; ++j)
29             ans+=cnt[num[j]]; tmp=0;
30     }
31     printf("%lld\n",ans);
32     return 0;
33 }
34 
35 int Aptal=Presist();
36 int main(int argc,char*argv[]){;}
60分 n^2
 1 /*
 2 将条件 满足(a,b)\x 的a,b数对个数 看作为
 3             存在 a*b*c<=n 的c 的取值
 4 则原问题转化为 找出a*b*c<=n 的a,b,c的组成发难书
 5 可以考虑 假设 a<=b<=c,通过枚举a,b累加ans 
 6 可以发现a*a*a<=n,b*b<=n/a,所以复杂度 根号5/6 
 7 */
 8 #include <cstdio>
 9 
10 #define LL long long
11 #ifdef WIN32
12 #define L_ "%I64d"
13 #else
14 #define L_ "%lld"
15 #endif
16 
17 inline void read(LL &x)
18 {
19     x=0; register char ch=getchar();
20     for(; ch>'9'||ch<'0'; ) ch=getchar();
21     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
22 }
23 LL n,ans,cnt;
24 
25 int Presist()
26 {
27     read(n);
28     for(LL i=1,t; i*i<=(t=n/i); ++i)
29       for(LL j=i+1; j*j<=t; ++j)
30         cnt+=n/(i*j)-j;    //此时假定a<b<c,cnt累加三个数的不同种类数 
31     ans+=cnt*6; cnt=0; // C(3,3) 累加ans 
32     for(LL i=1,t; (t=i*i)<=n; ++i)
33     {
34         cnt+=n/t;    //此时假定a=b ,cnt累加a的种类数 
35         if(t<=n/i) ans++,cnt--;//此时a==b==c单独累加ans 
36     }
37     ans+=cnt*3; //三个数中仅存在两个数相同的组合数 
38     printf(L_ "\n",ans);
39     return 0;
40 }
41 
42 int Aptal=Presist();
43 int main(int argc,char*argv[]){;}
AC

 

 

T2 b

【问题描述】
你是能看到第二题的 friends呢。
—— laekov
Hja和 Yjq为了 抢男主 角打了 起来 ,现在 他们 正在 一棵树 上决斗 。Hja在 A点,Yjq在 B点,Hja先发制人 开始 移动 。每次 他们 可以 沿着 一条边 移动 ,但 一旦 一条边 被对方 走过了 自己 就不能 再走这条边 了。每条 边上 都有 权值 ,他们 都希望 自己 的权值 尽量多 。现在 给你 这棵树 以及 他们 俩开始 的位置 ,问 Hja能 够获得 的最大权值 。
【输入格式】
第一行 两个 整数 𝑁,𝑀,代表 树的点数 和询问 的个数 。
接下来 𝑁−1行每行 三个 整数 𝑎,𝑏,𝑐,代表 从𝑎到𝑏有一条 权值 为𝑐的边 。
接下来 𝑀行,每行 两个整数 𝐴,𝐵代表 一次 询问 。
【输出格式】
对于 每次 询问 ,输出 一个 整数 代表 答案 。
【样例输入1】
2 1
1 2 3
1 2
【样例输出1】 3
【样例输入2】
3 2
1 2 3
1
3 2 3
1 3
【样例输出2】 3 4
P98 zhxb
第 4 页 共 6 页
【数据范围与规定】
对于 30%的数据 ,1≤𝑁,𝑀≤1000。
对于另外 30%的数据 ,𝑀=1。
对于 100%的数据, 1≤𝑁,𝑀≤105,0≤𝑐≤103,1≤𝑎,𝑏,𝐴,𝐵≤𝑁。

  1 /*
  2 分情况讨论增加ans 
  3 倍增LCA 维护一条链上的点权和 
  4 */
  5 #include<algorithm>
  6 #include<cstdlib>
  7 #include<cstring>
  8 #include<cstdio>
  9 
 10 using namespace std;
 11 
 12 const int maxn=100010;
 13 
 14 int n,m,en;
 15 int z[maxn*3],f[maxn][20],q[maxn],depth[maxn];
 16 sum[maxn*3][2],fd[maxn],start[maxn],end[maxn],value[maxn];
 17 
 18 struct edge
 19 {
 20     int e,d;
 21     edge *next;
 22 }*v[maxn],ed[maxn<<1];
 23 
 24 void add_edge(int s,int e,int d)
 25 {
 26     en++;
 27     v[s].e=e;v[s].d=d;
 28     ed[en].next=v[s];v[s]=ed+en;
 29 }
 30 
 31 int get(int p,int d)
 32 {
 33     if (d==-1) return p;
 34     int x=0;
 35     while (d)
 36     {
 37         if (d&1) p=f[p][x];
 38         d>>=1;
 39         x++;
 40     }
 41     return p;
 42 }
 43 
 44 int get_lca(int p1,int p2)
 45 {
 46     if (depth[p1]<depth[p2]) swap(p1,p2);
 47     p1=get(p1,depth[p1]-depth[p2]);
 48     int x=0;
 49     while (p1!=p2)
 50     {
 51         if (!x || f[p1][x]!=f[p2][x])
 52         {
 53             p1=f[p1][x];
 54             p2=f[p2][x];
 55             x++;
 56         }
 57         else x--;
 58     }
 59     return p1;
 60 }
 61 
 62 int calc(int p1,int p2)
 63 {
 64     if (p1==f[p2][0]) return value[1]-value[p2];
 65     else return value[p1]+fd[p1];
 66 }
 67 
 68 int calcp(int p,int v)
 69 {
 70     int l=start[p]-1,r=end[p];
 71     while (l+1!=r)
 72     {
 73         int m=(l+r)>>1;
 74         if (v>z[m]) l=m;
 75         else r=m;
 76     }
 77     return r;
 78 }
 79 
 80 int main()
 81 {
 82     freopen("b.in","r",stdin);
 83     freopen("b.out","w",stdout);
 84 
 85     scanf("%d%d",&n,&m);
 86     int tot=0;
 87     for (int a=1;a<n;a++)
 88     {
 89         int s,e,d;
 90         scanf("%d%d%d",&s,&e,&d);
 91         tot+=d;
 92         add_edge(s,e,d);
 93         add_edge(e,s,d);
 94     }
 95     depth[1]=1;
 96     int front=1,tail=1;
 97     q[1]=1;
 98     for (;front<=tail;)
 99     {
100         int now=q[front++];
101         for (edge *e=v[now];e;e=e->next)
102             if (!depth[e.e])
103             {
104                 depth[e.e]=depth[now]+1;
105                 fd[e.e]=e->d;
106                 f[e.e][0]=now;
107                 int p=now,x=0;
108                 while (f[p][x])
109                 {
110                     f[e.e][x+1]=f[p][x];
111                     p=f[p][x];
112                     x++;
113                 }
114                 q[++tail]=e.e;
115             }
116     }
117     int cnt=0;
118     for (int a=n;a>=1;a--)
119     {
120         int now=q[a];
121         start[now]=cnt+1;
122         for (edge *e=v[now];e;e=e.next)
123             if (depth[e.e]==depth[now]+1)
124             {
125                 z[++cnt]=value[e.e]+e.d;
126                 value[now]+=value[e.e]+e.d;
127             }
128         z[++cnt]=tot-value[now];
129         end[now]=cnt;
130         sort(z+start[now],z+end[now]+1);
131         sum[end[now]][0]=z[end[now]];
132         sum[end[now]][1]=0;
133         for (int a=end[now]-1;a>=start[now];a--)
134         {
135             sum[a][0]=sum[a+1][0];
136             sum[a][1]=sum[a+1][1];
137             if ((a&1)==(end[now]&1)) sum[a][0]+=z[a];
138             else sum[a][1]+=z[a];
139         }
140         cnt++;
141     }
142     for (int a=1;a<=m;a++)
143     {
144         int p1,p2;
145         scanf("%d%d",&p1,&p2);
146         int lca=get_lca(p1,p2);
147         int dist=depth[p1]+depth[p2]-2*depth[lca];
148         int delta=dist/2+(dist&1);
149         int px,px1,px2;
150         if (depth[p1]-depth[lca]<delta) px=get(p2,dist-delta);
151         else px=get(p1,delta);
152         if (depth[p1]-depth[lca]<delta-1) px1=get(p2,dist-delta+1);
153         else px1=get(p1,delta-1);
154         if (depth[p2]-depth[lca]<dist-delta-1) px2=get(p1,delta+1);
155         else px2=get(p2,dist-delta-1);
156         int ans=0;
157         if (p1==px)
158         {
159             if (p2==px) ans=sum[start[px]][0];
160             else
161             {
162                 int v2=calc(px2,px);
163                 int p=calcp(px,v2);
164                 ans=sum[p+1][0]+sum[start[px]][1]-sum[p][1];
165             }
166         }
167         else
168         {
169             if (p2==px)
170             {
171                 int v1=calc(px1,px);
172                 int p=calcp(px,v1);
173                 ans=v1+sum[p+1][1]+sum[start[px]][0]-sum[p][0];
174             }
175             else
176             {
177                 int v1=calc(px1,px);
178                 int pp1=calcp(px,v1);
179                 int v2=calc(px2,px);
180                 int pp2=calcp(px,v2);
181                 if (pp2==pp1) pp2++;
182                 if (pp1>pp2) swap(pp1,pp2);
183                 ans=v1+sum[pp2+1][dist&1]+sum[pp1+1][1-(dist&1)]-
184                        sum[pp2][1-(dist&1)]+sum[start[px]][dist&1]-sum[pp1][dist&1];
185             }
186         }
187         printf("%d\n",ans);
188     }
189     return 0;
190 }
AC

 

 

 


P98 zhxc
第 5 页 共 6 页

T3 c

【问题描述】
你是能看到第三题的 friends呢。
—— aoao
Yjq买了 36个卡包,并且把他们排列成 6×6的阵型准备开包 。左上角是(0,0),右下角为 ,右下角为 (5,5)。为了能够开到更多的金色普通卡, 。为了能够开到更多的金色普通卡, Yjq会为每个包添加 1−5个玄学值,每可以是 个玄学值,每可以是 1−30中的一个整数。但是不同玄学值会造 中的一个整数。但是不同玄学值会造 成不同的欧气加,具体如下:
1、同一个卡包如果有两相的玄学值会无限大欧气加成。
2、同一个卡包如果 有 两个相邻的玄学值会𝐴点欧气加成。
3、相邻的两个卡包如果有 同玄学值会𝐵点欧气加成。
4、相邻的两个卡包如果有 玄学值会𝐶点欧气加成。
5、距离为 2的卡包如果有 相同玄学值会𝐷点欧气加成。
6、距离为 2的卡包如果有 相邻玄学值会𝐸点欧气加成。
以上的所有 加成是每存在一个符合条件就会次,如包卡以上的所有 加成是每存在一个符合条件就会次,如包卡1,2,3的玄 学值就会加两次。
但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使但是 ,玄学值个不可控的东西即使Yjq也只能自己决定 也只能自己决定 也只能自己决定 也只能自己决定 也只能自己决定 也只能自己决定 也只能自己决定 (2,2),(2,3),(3,2),(3,3)这几包卡的玄学值。为了能够抽到更多金色普通, 这几包卡的玄学值。为了能够抽到更多金色普通, Yjq想知道自己能够获得的最 少的欧气加成是多。 注意 你只能 修改 玄学值 ,不能 修 改玄学值 的个数 。
【输入格式】
输入的第一行有 5个整数 𝐴,𝐵,𝐶,𝐷,𝐸。
接下去有 6×6的代表初始玄学值。
每个玄学值为 [𝑛:𝑎1,𝑎2,⋯,𝑎𝑛]的描述形式。
【输出格式】
一行个整数代表答案。
【样例输入】
5 4 3 2 1
[1:1][2][3][4][5][6]
[1:1][2][3][4][5][6]
[1:1][2][5:1,2,3,4,5][5][6]
[1:1][ 1:2][5:1,2,3,4,5][5][6]
[1:1][2][3][4][5][6]
[1:1][2][3][4][5][6]
P98 zhxc
第 6 页 共 6 页
【样例输出】
250
【数据规模与约定】
对于 100%的数据, 1≤𝐴,𝐵,𝐶,𝐷,𝐸≤100,1≤𝑛≤5,1≤𝑎𝑖≤30。有部分 。有部分 。

 

 

  1 /*
  2 九维DP
  3 维护点之间的最小价值 
  4 */
  5 #include<algorithm>
  6 #include<cstdlib>
  7 #include<cstring>
  8 #include<cstdio>
  9 
 10 using namespace std;
 11 
 12 #define now pre[a][b][c][d][e][s1][s2][s3][s4]
 13 #define dis(a,b,c,d) (abs(a-c)+abs(b-d))
 14 
 15 const int INF=0x3f3f3f3f;
 16 
 17 int A,B,C,D,E,num[10][10],value[10][10][10],delta[10][10][40],dp[31][6][6][6][6][2][2][2][2];
 18 
 19 char s[500];
 20 
 21 bool map[6][6][6][6];
 22 
 23 int main()
 24 {
 25     freopen("c.in","r",stdin);
 26     freopen("c.out","w",stdout);
 27 
 28     scanf("%d%d%d%d%d",&A,&B,&C,&D,&E);
 29     for (int a=0;a<6;a++)
 30     {
 31         scanf("%s",s);
 32         int p=0;
 33         for (int b=0;b<6;b++)
 34         {
 35             int px=p;
 36             while (s[px]!=']')
 37                 px++;
 38             p++;
 39             num[a][b]=s[p]-'0';
 40             p++;
 41             p++;
 42             for (int c=1;c<=num[a][b];c++)
 43             {
 44                 int v=0;
 45                 while (s[p]>='0' && s[p]<='9')
 46                 {
 47                     v=v*10+s[p]-'0';
 48                     p++;
 49                 }
 50                 value[a][b][c]=v;
 51                 p++;
 52             }
 53             p=px+1;
 54         }
 55     }
 56     int base=0;
 57     for (int a=0;a<6;a++)
 58         for (int b=0;b<6;b++)
 59             if (a>=2 && a<=3 && b>=2 && b<=3) ;
 60             else
 61             {
 62                 sort(value[a][b]+1,value[a][b]+num[a][b]+1);
 63                 for (int c=2;c<=num[a][b];c++)
 64                     if (value[a][b][c]-value[a][b][c-1]==1) base+=A;
 65                 for (int c=2;c<=3;c++)
 66                     for (int d=2;d<=3;d++)
 67                     {
 68                         if (dis(a,b,c,d)==1)
 69                         {
 70                             for (int e=1;e<=num[a][b];e++)
 71                             {
 72                                 delta[c][d][value[a][b][e]]+=B;
 73                                 delta[c][d][value[a][b][e]-1]+=C;
 74                                 delta[c][d][value[a][b][e]+1]+=C;
 75                             }
 76                         }
 77                         if (dis(a,b,c,d)==2)
 78                         {
 79                             for (int e=1;e<=num[a][b];e++)
 80                             {
 81                                 delta[c][d][value[a][b][e]]+=D;
 82                                 delta[c][d][value[a][b][e]-1]+=E;
 83                                 delta[c][d][value[a][b][e]+1]+=E;
 84                             }
 85                         }
 86                     }
 87                 for (int c=0;c<6;c++)
 88                     for (int d=0;d<6;d++)
 89                         if (dis(a,b,c,d)<=2 && (c!=a || d!=b) && !map[a][b][c][d])
 90                         {
 91                             map[a][b][c][d]=map[c][d][a][b]=true;
 92                             if (c>=2 && c<=3 && d>=2 && d<=3) ;
 93                             else
 94                             {
 95                                 int dist=dis(a,b,c,d);
 96                                 for (int e=1;e<=num[a][b];e++)
 97                                     for (int f=1;f<=num[c][d];f++)
 98                                     {
 99                                         if (abs(value[a][b][e]-value[c][d][f])==0)
100                                         {
101                                             if (dist==1) base+=B;
102                                             else base+=D;
103                                         }
104                                         if (abs(value[a][b][e]-value[c][d][f])==1)
105                                         {
106                                             if (dist==1) base+=C;
107                                             else base+=E;
108                                         }
109                                     }
110                             }
111                         }
112             }
113     memset(dp,0x3f,sizeof(dp));
114     dp[0][0][0][0][0][0][0][0][0]=base;
115     for (int a=0;a<30;a++)
116         for (int b=0;b<=num[2][2];b++)
117             for (int c=0;c<=num[2][3];c++)
118                 for (int d=0;d<=num[3][2];d++)
119                     for (int e=0;e<=num[3][3];e++)
120                         for (int s1=0;s1<=1;s1++)
121                             for (int s2=0;s2<=1;s2++)
122                                 for (int s3=0;s3<=1;s3++)
123                                     for (int s4=0;s4<=1;s4++)
124                                         if (dp[a][b][c][d][e][s1][s2][s3][s4]!=INF)
125                                         {
126                                             int v=dp[a][b][c][d][e][s1][s2][s3][s4];
127                                             for (int sx1=0;sx1<=(b!=num[2][2]);sx1++)
128                                                 for (int sx2=0;sx2<=(c!=num[2][3]);sx2++)
129                                                     for (int sx3=0;sx3<=(d!=num[3][2]);sx3++)
130                                                         for (int sx4=0;sx4<=(e!=num[3][3]);sx4++)
131                                                         {
132                                                             int wmt=0;
133                                                             if (sx1) 
134                                                             {
135                                                                 wmt+=delta[2][2][a+1];
136                                                                 if (s1) wmt+=A;
137                                                                 if (s2) wmt+=C;
138                                                                 if (s3) wmt+=C;
139                                                                 if (s4) wmt+=E;
140                                                             }
141                                                             if (sx2) 
142                                                             {
143                                                                 wmt+=delta[2][3][a+1];
144                                                                 if (s1) wmt+=C;
145                                                                 if (s2) wmt+=A;
146                                                                 if (s3) wmt+=E;
147                                                                 if (s4) wmt+=C;
148                                                             }
149                                                             if (sx3) 
150                                                             {
151                                                                 wmt+=delta[3][2][a+1];
152                                                                 if (s1) wmt+=C;
153                                                                 if (s2) wmt+=E;
154                                                                 if (s3) wmt+=A;
155                                                                 if (s4) wmt+=C;
156                                                             }
157                                                             if (sx4) 
158                                                             {
159                                                                 wmt+=delta[3][3][a+1];
160                                                                 if (s1) wmt+=E;
161                                                                 if (s2) wmt+=C;
162                                                                 if (s3) wmt+=C;
163                                                                 if (s4) wmt+=A;
164                                                             }
165                                                             if (sx1 && sx2) wmt+=B;
166                                                             if (sx1 && sx3) wmt+=B;
167                                                             if (sx1 && sx4) wmt+=D;
168                                                             if (sx2 && sx3) wmt+=D;
169                                                             if (sx2 && sx4) wmt+=B;
170                                                             if (sx3 && sx4) wmt+=B;
171                                                             int &t=dp[a+1][b+sx1][c+sx2][d+sx3][e+sx4][sx1][sx2][sx3][sx4];
172                                                             if (t>v+wmt) t=v+wmt;
173                                                         }
174                                         }
175     int ans=INF;
176     for (int a=0;a<=1;a++)
177         for (int b=0;b<=1;b++)
178             for (int c=0;c<=1;c++)
179                 for (int d=0;d<=1;d++)
180                     ans=min(ans,dp[30][num[2][2]][num[2][3]][num[3][2]][num[3][3]][a][b][c][d]);
181     printf("%d\n",ans);
182 
183     return 0;
184 }
AC

 

posted @ 2017-10-09 20:35  Aptal丶  阅读(295)  评论(0编辑  收藏  举报