北京集训DAY2

 1 /*
 2     我们所要求得是(a*b)|x 
 3     也就是 使(a*b)的倍数小于x的个数之和 1<=x<=n 
 4     我们可以 找一个c使得 (a*b*c)<=x  
 5     由于我们所求的是一个三元有序对 即 (1,2,3) 与 (1,3,2) 是两种不同的方案数
 6     所以 我们可以强制规定 a<b<c 
 7     最坏的情况是(a*a*a)==x  所以我们就可以确定a的枚举范围 就是n开三次根号
 8     同理 b最大枚举到 sqrt(n/a) 
 9     n/(a*b) 即为 c 由于c>b>a 所以 我们枚举的c是大于b的 
10     c的实际个数为 n(a*b)-b 
11     每一个三元有序对一共有六种变换方式 最后*6加进ans 
12     
13     还有一种情况是 a,b,c 中有两个数相等 例如 a==b>c 
14     我们只需要枚举 c==n/(a*a) 的个数 
15     每一个三元有序对 可以有三种变换  枚举的c的个数最后*3 加进ans 
16     
17     最后一种情况就是 a==b==c 对ans的贡献为 1 简单判断一下就好了 
18 */ 
19 #include<cstdio>
20 #include<cstdlib>
21 #include<cstring>
22 
23 typedef long long LL;
24 
25 using namespace std;
26 
27 LL n;
28 
29 #ifdef unix
30 #define ll "%lld"
31 #else
32 #define ll "%I64d"
33 #endif
34 
35 int hh() {
36     freopen("a.in","r",stdin);
37     freopen("a.out","w",stdout);
38     scanf(ll,&n);
39     LL ans=0,tmp=0;
40     for(LL a=1,v;a*a<=(v=n/a);a++,ans++)
41         for(LL b=a+1;b*b<=v;b++)
42             tmp+=n/(a*b)-b;
43     ans+=tmp*6;
44     tmp=0;
45     for(LL a=1,v;(v=a*a)<=n;a++) {
46         tmp+=n/v;
47         if(a*a<=n/a) tmp--;
48     }
49     ans+=tmp*3;
50     printf(ll "\n",ans);
51     return 0;
52 }
53 
54 int sb=hh();
55 int main(int argc,char**argv) {;}
题解

 

  1 /*
  2     倍增LCA 巧妙地搞一搞 
  3     对于两个人 想要最大的权值 一定要先把对方给封锁 
  4     就是 让对方走过的点越少越好 
  5     所以 两个人 一定是先对着走 
  6     树上任意两个点之间的路径是唯一的 所以两个人碰面的点 也是一定的 
  7     即为 两个人之间点数的中位数 
  8     这个点用LCA 求出 
  9     求出之后 这个点还可能连着多条边 
 10     对于先手会先选一颗权值最大的子树 先走一条边
 11     后手会选次大的子树 走一条边
 12     两者退回继续选取要走的子树 
 13     直到走不动了 
 14     最后ans再加上已经占领的子树的权值 即为最大权值 
 15 */
 16 #include<cstdio>
 17 #include<cstdlib>
 18 #include<cstring>
 19 #include<algorithm>
 20 
 21 using namespace std;
 22 
 23 const int MAXN=100010;
 24 
 25 int n,m,en,z[MAXN*3],f[MAXN][21],q[MAXN],depth[MAXN],sum[MAXN*3][2],fd[MAXN];
 26 
 27 int start[MAXN],end[MAXN],value[MAXN];
 28 
 29 struct edge {
 30     int e,d;
 31     edge *next;
 32 }*v[MAXN],ed[MAXN<<1];
 33 
 34 inline void add_edge(int s,int e,int d) {
 35     en++;
 36     ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;v[s]->d=d;
 37 }
 38 
 39 int get(int p,int d) {
 40     if(d==-1) return p;
 41     int x=0;
 42     while(d) {
 43         if(d&1) p=f[p][x];
 44         d>>=1;
 45         x++;
 46     }
 47     return p;
 48 }
 49 
 50 int get_lca(int p1,int p2) {
 51     if(depth[p1]<depth[p2]) swap(p1,p2);
 52     p1=get(p1,depth[p1]-depth[p2]);
 53     int x=0;
 54     while(p1!=p2) {
 55         if(!x||f[p1][x]!=f[p2][x]) {
 56             p1=f[p1][x];
 57             p2=f[p2][x];
 58             x++;
 59         }
 60         else x--;
 61     }
 62     return p1;
 63 }
 64 
 65 inline int calc(int p1,int p2) {
 66     if(p1==f[p2][0]) return value[1]-value[p2];
 67     else return value[p1]+fd[p1];
 68 }
 69 
 70 int calcp(int p,int v) {
 71     int l=start[p]-1,r=end[p];
 72     while(l+1!=r) {
 73         int m=(l+r)>>1;
 74         if(v>z[m]) l=m;
 75         else r=m;
 76     }
 77     return r;
 78 }
 79 
 80 void BFS() {
 81     depth[1]=1;
 82     int front=1,tail=1;
 83     q[1]=1;
 84     for(;front<=tail;) {
 85         int now=q[front++];
 86         for(edge *e=v[now];e;e=e->next)
 87             if(!depth[e->e]) {
 88                 depth[e->e]=depth[now]+1;
 89                 fd[e->e]=e->d;
 90                 f[e->e][0]=now;
 91                 int p=now,x=0;
 92                 while(f[p][x]) {
 93                     f[e->e][x+1]=f[p][x];
 94                     p=f[p][x];
 95                     x++;
 96                 }
 97                 q[++tail]=e->e;
 98             }
 99     }
100     return;
101 }
102 
103 int hh(){
104     freopen("b.in","r",stdin);
105     freopen("b.out","w",stdout);
106     scanf("%d%d",&n,&m);
107     int tot=0;
108     for(int a=1;a<n;a++) {
109         int s,e,d;
110         scanf("%d%d%d",&s,&e,&d);
111         tot+=d;
112         add_edge(s,e,d);
113         add_edge(e,s,d);
114     }
115     BFS(); 
116     int cnt=0;
117     for(int a=n;a>=1;a--) {
118         int now=q[a];
119         start[now]=cnt+1;
120         for(edge *e=v[now];e;e=e->next)
121             if(depth[e->e]==depth[now]+1) {
122                 z[++cnt]=value[e->e]+e->d;
123                 value[now]+=value[e->e]+e->d;
124             }
125         z[++cnt]=tot-value[now];
126         end[now]=cnt;
127         sort(z+start[now],z+end[now]+1);
128         sum[end[now]][0]=z[end[now]];
129         sum[end[now]][1]=0;
130         for(int a=end[now]-1;a>=start[now];a--) {
131             sum[a][0]=sum[a+1][0];
132             sum[a][1]=sum[a+1][1];
133             if((a&1)==(end[now]&1)) sum[a][0]+=z[a];
134             else sum[a][1]+=z[a];
135         }
136         cnt++;
137     }
138     for(int a=1;a<=m;a++) {
139         int p1,p2;
140         scanf("%d%d",&p1,&p2);
141         int lca=get_lca(p1,p2);
142         int dist=depth[p1]+depth[p2]-2*depth[lca];
143         int delta=dist/2+(dist&1);
144         int px,px1,px2;
145         if(depth[p1]-depth[lca]<delta) px=get(p2,dist-delta);
146         else px=get(p1,delta);
147         if(depth[p1]-depth[lca]<delta-1) px1=get(p2,dist-delta+1);
148         else px1=get(p1,delta-1);
149         if(depth[p2]-depth[lca]<dist-delta-1) px2=get(p1,delta+1);
150         else px2=get(p2,dist-delta-1);
151         int ans=0;
152         if(p1==px) {
153             if(p2==px) ans=sum[start[px]][0];
154             else {
155                 int v2=calc(px2,px);
156                 int p=calcp(px,v2);
157                 ans=sum[p+1][0]+sum[start[px]][1]-sum[p][1];
158             }
159         }
160         else {
161             if(p2==px) {
162                 int v1=calc(px1,px);
163                 int p=calcp(px,v1);
164                 ans=v1+sum[p+1][1]+sum[start[px]][0]-sum[p][0];
165             }
166             else {
167                 int v1=calc(px1,px);
168                 int pp1=calcp(px,v1);
169                 int v2=calc(px2,px);
170                 int pp2=calcp(px,v2);
171                 if(pp2==pp1) pp2++;
172                 if(pp1>pp2) swap(pp1,pp2);
173                 ans=v1+sum[pp2+1][dist&1]+sum[pp1+1][1-(dist&1)]-sum[pp2][1-(dist&1)]+sum[start[px]][dist&1]-sum[pp1][dist&1];
174             }
175         }
176         printf("%d\n",ans);
177     }
178     return 0;
179 }
180 
181 int sb=hh();
182 int main(int argc,char**argv) {;}
题解

 

 

  1 /*
  2     考试时第一眼就是不可做 
  3     然后想了一想 好像可以搜索 但是根本写不出来
  4     
  5     正解是 搜索加9维DP 
  6     题目中说了 只有四个卡包是可以修改的 
  7     所以其他的卡包的欧气加成用搜索来计算 
  8     
  9     对于可以修改的四个卡包 我们用DP处理修改不同的值使它与四周产生的欧气加成
 10     最后统计最小值 
 11 */
 12 #include<cstdio>
 13 #include<cstdlib>
 14 #include<cstring>
 15 #include<algorithm>
 16 
 17 using namespace std;
 18 
 19 #define now pre[a][b][c][d][e][s1][s2][s3][s4]
 20 #define dis(a,b,c,d) (abs(a-c)+abs(b-d))
 21 
 22 const int INF=0x3f3f3f3f;
 23 
 24 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];
 25 
 26 char s[500];
 27 
 28 bool map[6][6][6][6];
 29 
 30 int main() {
 31     freopen("c.in","r",stdin);
 32     freopen("c.out","w",stdout);
 33 
 34     scanf("%d%d%d%d%d",&A,&B,&C,&D,&E);
 35     for(int a=0;a<6;a++) {
 36         scanf("%s",s);
 37         int p=0;
 38         for(int b=0;b<6;b++) {
 39             int px=p;
 40             while(s[px]!=']') px++;
 41             p++;
 42             num[a][b]=s[p]-'0';
 43             p++;p++;
 44             for(int c=1;c<=num[a][b];c++) {
 45                 int v=0;
 46                 while(s[p]>='0'&&s[p]<='9') v=v*10+s[p]-'0',p++;
 47                 value[a][b][c]=v;
 48                 p++;
 49             }
 50             p=px+1;
 51         }
 52     }
 53     int base=0;
 54     for(int a=0;a<6;a++)
 55         for(int b=0;b<6;b++)
 56             if(a>=2&&a<=3&&b>=2&&b<=3) ;
 57             else {
 58                 sort(value[a][b]+1,value[a][b]+num[a][b]+1);
 59                 for(int c=2;c<=num[a][b];c++)
 60                     if(value[a][b][c]-value[a][b][c-1]==1) base+=A;
 61                 for(int c=2;c<=3;c++)
 62                     for(int d=2;d<=3;d++) {
 63                         if(dis(a,b,c,d)==1) {
 64                             for(int e=1;e<=num[a][b];e++) {
 65                                 delta[c][d][value[a][b][e]]+=B;
 66                                 delta[c][d][value[a][b][e]-1]+=C;
 67                                 delta[c][d][value[a][b][e]+1]+=C;
 68                             }
 69                         }
 70                         if(dis(a,b,c,d)==2) {
 71                             for(int e=1;e<=num[a][b];e++) {
 72                                 delta[c][d][value[a][b][e]]+=D;
 73                                 delta[c][d][value[a][b][e]-1]+=E;
 74                                 delta[c][d][value[a][b][e]+1]+=E;
 75                             }
 76                         }
 77                     }
 78                 for(int c=0;c<6;c++)
 79                     for(int d=0;d<6;d++)
 80                         if(dis(a,b,c,d)<=2 && (c!=a || d!=b) && !map[a][b][c][d]) {
 81                             map[a][b][c][d]=map[c][d][a][b]=true;
 82                             if(c>=2&&c<=3&&d>=2&&d<=3) ;
 83                             else {
 84                                 int dist=dis(a,b,c,d);
 85                                 for(int e=1;e<=num[a][b];e++)
 86                                     for(int f=1;f<=num[c][d];f++) {
 87                                         if(abs(value[a][b][e]-value[c][d][f])==0) {
 88                                             if(dist==1) base+=B;
 89                                             else base+=D;
 90                                         }
 91                                         if(abs(value[a][b][e]-value[c][d][f])==1) {
 92                                             if(dist==1) base+=C;
 93                                             else base+=E;
 94                                         }
 95                                     }
 96                             }
 97                         }
 98             }
 99     memset(dp,0x3f,sizeof(dp));
100     dp[0][0][0][0][0][0][0][0][0]=base;
101     for(int a=0;a<30;a++)
102         for(int b=0;b<=num[2][2];b++)
103             for(int c=0;c<=num[2][3];c++)
104                 for(int d=0;d<=num[3][2];d++)
105                     for(int e=0;e<=num[3][3];e++)
106                         for(int s1=0;s1<=1;s1++)
107                             for(int s2=0;s2<=1;s2++)
108                                 for(int s3=0;s3<=1;s3++)
109                                     for(int s4=0;s4<=1;s4++)
110                                         if(dp[a][b][c][d][e][s1][s2][s3][s4]!=INF) {
111                                             int v=dp[a][b][c][d][e][s1][s2][s3][s4];
112                                             for(int sx1=0;sx1<=(b!=num[2][2]);sx1++)
113                                                 for(int sx2=0;sx2<=(c!=num[2][3]);sx2++)
114                                                     for(int sx3=0;sx3<=(d!=num[3][2]);sx3++)
115                                                         for(int sx4=0;sx4<=(e!=num[3][3]);sx4++) {
116                                                             int wmt=0;
117                                                             if(sx1) {
118                                                                 wmt+=delta[2][2][a+1];
119                                                                 if(s1) wmt+=A;
120                                                                 if(s2) wmt+=C;
121                                                                 if(s3) wmt+=C;
122                                                                 if(s4) wmt+=E;
123                                                             }
124                                                             if(sx2) {
125                                                                 wmt+=delta[2][3][a+1];
126                                                                 if(s1) wmt+=C;
127                                                                 if(s2) wmt+=A;
128                                                                 if(s3) wmt+=E;
129                                                                 if(s4) wmt+=C;
130                                                             }
131                                                             if(sx3) {
132                                                                 wmt+=delta[3][2][a+1];
133                                                                 if(s1) wmt+=C;
134                                                                 if(s2) wmt+=E;
135                                                                 if(s3) wmt+=A;
136                                                                 if(s4) wmt+=C;
137                                                             }
138                                                             if(sx4) {
139                                                                 wmt+=delta[3][3][a+1];
140                                                                 if(s1) wmt+=E;
141                                                                 if(s2) wmt+=C;
142                                                                 if(s3) wmt+=C;
143                                                                 if(s4) wmt+=A;
144                                                             }
145                                                             if(sx1&&sx2) wmt+=B;
146                                                             if(sx1&&sx3) wmt+=B;
147                                                             if(sx1&&sx4) wmt+=D;
148                                                             if(sx2&&sx3) wmt+=D;
149                                                             if(sx2&&sx4) wmt+=B;
150                                                             if(sx3&&sx4) wmt+=B;
151                                                             int &t=dp[a+1][b+sx1][c+sx2][d+sx3][e+sx4][sx1][sx2][sx3][sx4];
152                                                             if(t>v+wmt) t=v+wmt;
153                                                         }
154                                         }
155     int ans=INF;
156     for(int a=0;a<=1;a++)
157         for(int b=0;b<=1;b++)
158             for(int c=0;c<=1;c++)
159                 for(int d=0;d<=1;d++)
160                     ans=min(ans,dp[30][num[2][2]][num[2][3]][num[3][2]][num[3][3]][a][b][c][d]);
161     printf("%d\n",ans);
162 
163     return 0;
164 }
题解

 

posted @ 2017-10-10 09:51  拿叉插猹哈  阅读(91)  评论(0编辑  收藏  举报