北京集训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 }
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现