北京集训DAY2

来源:互联网 发布:linux查看内存位置 编辑:程序博客网 时间:2024/04/29 16:38

 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 unix30 #define ll "%lld"31 #else32 #define ll "%I64d"33 #endif34 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 }
题解

 

原创粉丝点击