终于考完了
----
诶--- --- ---
1.7
cf500c
http://codeforces.com/problemset/problem/500/C
补去年的题了......(不,,,是前年---呜呜呜--)
懒成狗了......
给出 n 本书的重量,m 天,还有这m 天每天要看哪一本书,然后每次看一本书的时候,是将这本书上面的书拿走,再拿走要看的书,再把挪走的那一摞书放回来
确定书最开始的顺序,使得搬的书的重量最小
按照看书的先后顺序来放,没有出现过的书就不管
假设现在要看的书是 x ,它的上面有 m 这么重的书
现在需要搬 m
如果不是按照看书的顺序来放的放,假设现在有一个m0在x 的上面
现在需要搬动 m + m0 > m


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 1005; 8 int a[maxn],w[maxn]; 9 int n,m; 10 int b[maxn],vis[maxn]; 11 int c[maxn]; 12 13 void solve(){ 14 int cnt = 0; 15 memset(vis,0,sizeof(vis)); 16 memset(c,0,sizeof(c)); 17 for(int i = 1;i <= m;i++){ 18 if(!vis[a[i]]){ 19 b[++cnt] = a[i]; 20 vis[a[i]] = 1; 21 } 22 } 23 24 /* for(int i = 1;i <= cnt;i++){ 25 printf("b[%d] = %d\n",i,b[i]); 26 }*/ 27 28 int ans = 0; 29 for(int i = 1;i <= m;i++){ 30 int pos = 0; 31 for(int j = 1;j <= cnt;j++){ 32 if(b[j] == a[i]) { 33 pos = j; 34 break; 35 } 36 ans += w[b[j]]; 37 // printf("--- i = %d b[%d] = %d\n",i,j,b[j]); 38 } 39 memcpy(c,b,sizeof(b)); 40 for(int j = 1;j < pos;j++){ 41 b[j+1] = c[j]; 42 } 43 b[1] = a[i]; 44 45 /* for(int j = 1;j <= cnt;j++){ 46 printf(" %d ",b[j]); 47 } 48 printf("\n");*/ 49 } 50 printf("%d\n",ans); 51 } 52 53 int main(){ 54 while(scanf("%d %d",&n,&m) != EOF){ 55 for(int i = 1;i <= n;i++) scanf("%d",&w[i]); 56 for(int i = 1;i <= m;i++) scanf("%d",&a[i]); 57 solve(); 58 } 59 return 0; 60 }
1.8
...今天做了一件sb的事情
是这样的--
cf 609e
http://codeforces.com/contest/609/problem/E
给出 n 个点,m条边的一个图,然后求使得mi 在最小生成树里面的时候 的 mst
先求出原图的mst
如果这条边在最小生成树上,就直接输出 mst
如果不在,就求出 lca(u,v),查询 u 到 lca , v 到 lca 的路径上的权值最大的一条边
(本来,,本来,求Lca的时候,就可以把这个最大值求出来的---,,,sb地以为要用树剖---
抄板抄了一下午,,,代码写了200多行---蠢哭了......),
再把这条边替换成mi就可以了---


1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<vector> 5 #include<map> 6 #include<set> 7 #include<queue> 8 #include<iostream> 9 #include<algorithm> 10 using namespace std; 11 #define lp (p << 1) 12 #define rp (p << 1 | 1) 13 #define getmid(l,r) (l+(r-l)/2) 14 typedef long long ll; 15 const int INF = 1 << 30; 16 const int maxn = 4e5+5; 17 const int MAX_LOG = 32; 18 19 int T,N,M; 20 int dep[maxn],sz[maxn],son[maxn],fa[MAX_LOG][maxn]; 21 int top[maxn],tsz,w[maxn],tmax[maxn<<2]; 22 int first[maxn]; 23 int ecnt; 24 int e[maxn][5]; 25 26 struct Edge{ 27 int u,v,w; 28 int nxt; 29 int tag; 30 int id; 31 }ee[maxn*2]; 32 33 int cmp(Edge n1,Edge n2){ 34 return n1.w < n2.w; 35 } 36 37 int cmp0(Edge n1,Edge n2){ 38 return n1.id < n2.id; 39 } 40 41 Edge edge[maxn*2]; 42 int pp[maxn]; 43 44 void Add_edge(int u,int v,int w){ 45 ee[++ecnt].nxt = first[u]; 46 ee[ecnt].v = v; 47 ee[ecnt].u = u; 48 ee[ecnt].w = w; 49 first[u] = ecnt; 50 } 51 52 int findfa(int x){ 53 return x == pp[x] ? x :pp[x] = findfa(pp[x]); 54 } 55 56 void Dfs(int p){ 57 // printf("p = %d\n",p); 58 sz[p] = 1; 59 son[p] = -1; 60 int maxx = 0; 61 int v; 62 for(int i = first[p];~i;i = ee[i].nxt){ 63 v = ee[i].v; 64 if(v == fa[0][p]) continue; 65 dep[v] = dep[p] + 1; 66 fa[0][v] = p; 67 Dfs(v); 68 if(sz[v] > maxx){ 69 son[p] = v; 70 maxx = sz[v]; 71 } 72 } 73 sz[p] += sz[v]; 74 } 75 76 void Build_tree(int p,int tp){ 77 w[p] = ++tsz; 78 top[p] = tp; 79 if(son[p] != -1) { 80 Build_tree(son[p],tp); 81 } 82 for(int i = first[p];~i;i = ee[i].nxt){ 83 int v = ee[i].v; 84 if(v != son[p] && v != fa[0][p]){ 85 Build_tree(v,v); 86 } 87 } 88 } 89 90 void Update_tree(int a,int v,int p,int l,int r){ 91 if(l == r){ 92 tmax[p] = v; 93 return; 94 } 95 int mid = getmid(l,r); 96 if(a <= mid) Update_tree(a,v,lp,l,mid); 97 else Update_tree(a,v,rp,mid+1,r); 98 tmax[p] = max(tmax[lp],tmax[rp]); 99 } 100 101 int Query_tree(int a,int b,int p,int l,int r){ 102 if(a <= l && r <= b) return tmax[p]; 103 int res = -INF; 104 int mid = getmid(l,r); 105 if(a <= mid) res = max(res,Query_tree(a,b,lp,l,mid)); 106 if(b > mid) res = max(res,Query_tree(a,b,rp,mid+1,r)); 107 return res; 108 } 109 110 int Find(int a,int b){ 111 int f1 = top[a],f2 = top[b]; 112 int ans = 0; 113 while(f1 != f2){ 114 if(dep[f1] > dep[f2]){ 115 swap(a,b); 116 swap(f1,f2); 117 } 118 ans = max(ans,Query_tree(w[f2],w[b],1,1,tsz)); 119 b = fa[0][f2]; 120 f2 = top[b]; 121 } 122 if(a == b) return ans; 123 if(dep[a] > dep[b]) swap(a,b); 124 return max(ans,Query_tree(w[son[a]],w[b],1,1,tsz)); 125 } 126 127 void Init(){ 128 tsz = -1; 129 fa[0][1] = dep[1] = 0; 130 memset(sz,0,sizeof(sz)); 131 memset(tmax,0,sizeof(tmax)); 132 memset(first,-1,sizeof(first)); 133 ecnt = 0; 134 } 135 136 void Pre(){ 137 for(int k = 0; k + 1 < MAX_LOG; ++k){ 138 for(int v = 1; v <= N; ++v){ 139 if(fa[k][v] < 0) fa[k + 1][v] = -1; 140 else fa[k + 1][v] = fa[k][fa[k][v]]; 141 } 142 } 143 } 144 145 int Lca(int u,int v){ 146 if(dep[u] > dep[v]) swap(u,v); 147 for(int k = MAX_LOG - 1; k >= 0; --k){ 148 if((dep[v] - dep[u]) & (1 << k)) 149 v = fa[k][v]; 150 } 151 if(u == v) return u; //u为v的根 152 for(int k = MAX_LOG - 1; k >= 0; --k){ 153 if(fa[k][u] != fa[k][v]){ 154 u = fa[k][u]; 155 v = fa[k][v]; 156 } 157 } 158 return fa[0][u]; //u离lca只差一步 159 } 160 161 int main(){ 162 char s[10]; 163 int a,b,c; 164 while(scanf("%d %d",&N,&M) != EOF){ 165 Init(); 166 for(int i = 1;i <= M;i++){ 167 scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w); 168 edge[i].id = i; 169 edge[i].tag = 0; 170 } 171 for(int i = 1;i <= N;i++) pp[i] = i; 172 sort(edge+1,edge+M+1,cmp); 173 ll mst = 0; 174 for(int i = 1;i <= M;i++){ 175 int u = edge[i].u; 176 int v = edge[i].v; 177 int x = findfa(u),y = findfa(v); 178 if(x != y){ 179 edge[i].tag = 1; 180 mst += 1ll*edge[i].w; 181 pp[x] = y; 182 } 183 } 184 185 /* for(int i = 1;i <= M;i++){ 186 printf("u = %d v = %d edge[%d].tag = %d\n",edge[i].u,edge[i].v,i,edge[i].tag); 187 }*/ 188 189 memset(e,0,sizeof(e)); 190 int cnt = 0; 191 for(int i = 1;i <= M;i++){ 192 if(edge[i].tag == 0) continue; 193 int a ,b,c; 194 a = edge[i].u; 195 b = edge[i].v; 196 c = edge[i].w; 197 e[++cnt][0] = a; 198 e[cnt][1] = b; 199 e[cnt][2] = c; 200 Add_edge(a,b,c); 201 Add_edge(b,a,c); 202 } 203 204 Dfs(1); 205 Build_tree(1,1); 206 for(int i = 1;i < N;i++){ 207 if(dep[e[i][0]] > dep[e[i][1]]) swap(e[i][0],e[i][1]); 208 Update_tree(w[e[i][1]],e[i][2],1,1,tsz); 209 } 210 /* for(int i = 1;i <= ecnt;i++){ 211 printf("ee[%d].u = %d v = %d\n",i,ee[i].u,ee[i].v); 212 } 213 214 /* for(int i = 1;i <= 5;i++){ 215 int u,v; 216 scanf("%d %d",&u,&v); 217 printf("---%d\n",Find(u,v)); 218 }*/ 219 220 sort(edge+1,edge+M+1,cmp0); 221 Pre(); 222 for(int i = 1;i <= M;i++){ 223 // printf("edge[%d].u = %d v = %d\n",i,edge[i].u,edge[i].v); 224 if(edge[i].tag == 1){ 225 printf("%I64d\n",mst); 226 continue; 227 } 228 int u = edge[i].u; 229 int v = edge[i].v; 230 int lca = Lca(u,v); 231 int maxx = 0; 232 maxx = max(maxx,Find(u,lca)); 233 maxx = max(maxx,Find(v,lca)); 234 ll res = 0; 235 res = mst - maxx + 1ll*edge[i].w; 236 printf("%I64d\n",res); 237 // printf("u = %d v = %d lca = %d\n",u,v,lca); 238 } 239 } 240 return 0; 241 }
1.9
滚回家
话说还以为一年没回家,,汽车站修成新的了,,后来才发现自己sb地坐过站了(压根不是一个地方嘛------)- -
1.10
cf 609d
http://codeforces.com/contest/609/problem/D
题意好绕阿
给出 n 天,m个物品,需要买k件物品,s 个burle ,每个物品对应有一个type 还有一个 c (汇率)
type 为 1 的物品只能够用美元来购买
type 为 2的物品只能够用英镑来购买
再分别给出这n天 的美元,英镑 对 burle 的汇率
问买够这k件物品至少需要花多少天,输出天数,再分别输出这k件物品分别是哪一天购买的
二分天数x,再贪心地求出 在这 x 天里面,对应的哪一天美元,英镑的汇率最低,
再用这个来算购买每个物品需要花的钱,升序排序,贪心买k个,看花的钱是不是<= s
----
本来这样是 t 了的,,于是跑去预处理了下那个汇率
还是 t 了---
后来发现二分50次的话,不用预处理汇率也可以---唉---


1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 8 typedef long long ll; 9 const int maxn = 4e5+5; 10 int a[maxn],b[maxn]; 11 int n,m,k,s; 12 13 struct node{ 14 int t,c; 15 ll w; 16 int id; 17 int tag; 18 }; 19 20 node p[maxn]; 21 22 int cmp(node n1,node n2){ 23 return n1.w < n2.w; 24 } 25 26 int cmp0(node n1,node n2){ 27 return n1.id < n2.id; 28 } 29 30 int ixd,ixp; 31 int pred[maxn][2]; 32 int prep[maxn][2]; 33 34 int ok(int x){ 35 int md = pred[x][0]; 36 int mp = prep[x][0]; 37 ixd = pred[x][1]; 38 ixp = prep[x][1]; 39 40 for(int i = 1;i <= m;i++){ 41 if(p[i].t == 1) p[i].w = 1ll*md*p[i].c; 42 else p[i].w = 1ll*mp*p[i].c; 43 } 44 sort(p+1,p+m+1,cmp); 45 ll res = 0; 46 for(int i = 1;i <= k;i++){ 47 res += 1ll*p[i].w; 48 } 49 //printf("x = %d res = %I64d md = %d mp = %d\n",x,res,md,mp); 50 return res <= s; 51 } 52 53 void solve(){ 54 pred[1][0] = a[1]; 55 pred[1][1] = 1; 56 prep[1][0] = b[1]; 57 prep[1][1] = 1; 58 59 for(int i = 2;i <= n;i++){ 60 if(a[i] < pred[i-1][0]){ 61 pred[i][0] = a[i]; 62 pred[i][1] = i; 63 } 64 else{ 65 pred[i][0] = pred[i-1][0]; 66 pred[i][1] = pred[i-1][1]; 67 } 68 69 if(b[i] < prep[i-1][0]){ 70 prep[i][0] = b[i]; 71 prep[i][1] = i; 72 } 73 else{ 74 prep[i][0] = prep[i-1][0]; 75 prep[i][1] = prep[i-1][1]; 76 } 77 } 78 79 int lb = 1,ub = n,mid; 80 int ans = 1e9+7; 81 int flag = 0; 82 for(int i = 0;i <= 50;i++){ 83 mid = (lb+ub)/2; 84 if(ok(mid)) { 85 ans = min(ans,mid); 86 ub = mid; 87 flag = 1; 88 } 89 else lb = mid+1; 90 // printf("mid = %d lb = %d ub = %d\n",mid,lb,ub); 91 } 92 if(!flag) puts("-1"); 93 else{ 94 printf("%d\n",ans); 95 for(int i = 1;i <= m;i++){ 96 if(i <= k) p[i].tag = 1; 97 else p[i].tag = 0; 98 } 99 sort(p+1,p+m+1,cmp0); 100 for(int i = 1;i <= m;i++){ 101 if(p[i].tag == 0) continue; 102 if(p[i].t == 1){ 103 printf("%d %d\n",p[i].id,ixd); 104 } 105 else{ 106 printf("%d %d\n",p[i].id,ixp); 107 } 108 } 109 } 110 } 111 112 int main(){ 113 while(scanf("%d %d %d %d",&n,&m,&k,&s) != EOF){ 114 for(int i = 1;i <= n;i++) scanf("%d",&a[i]); 115 for(int i = 1;i <= n;i++) scanf("%d",&b[i]); 116 for(int i = 1;i <= m;i++){ 117 scanf("%d %d",&p[i].t,&p[i].c); 118 p[i].id = i; 119 } 120 solve(); 121 } 122 return 0; 123 }
cf 608b
http://codeforces.com/contest/608/problem/B
很水很水的一道题了叭,,可是当时就是不会做,好笨阿
给出 a 串 和 b 串
定义 距离 为 d = b[i] - a[i];
求所有的 b 的长度 为 a 的子串的 d 之和
对应 a 串中的每一个字符,它在 b 串中有连续的一段区间
这段区间 为 [i,lenb-lena+i] (当时死活想不出这个区间是啥,,觉得边界会很麻烦,,可是就是是这样子了---唉--)
然后再算出 b 串 的前缀 0 的个数,前缀 1 的个数


1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 typedef long long LL; 8 const int maxn = 2e5+5; 9 int ling[maxn],yi[maxn]; 10 char a[maxn],b[maxn]; 11 12 void solve(){ 13 int lena = strlen(a+1); 14 int lenb = strlen(b+1); 15 memset(ling,0,sizeof(ling)); 16 memset(yi,0,sizeof(yi)); 17 for(int i = 1;i <= lenb;i++){ 18 if(b[i] == '0') ling[i] = ling[i-1]+1; 19 else ling[i] = ling[i-1]; 20 21 if(b[i] == '1') yi[i] = yi[i-1]+1; 22 else yi[i] = yi[i-1]; 23 } 24 25 /*for(int i = 1;i <= lenb;i++){ 26 printf("ling[%d] = %d\n",i,ling[i]); 27 printf("yi[%d] = %d\n",i,yi[i]); 28 }*/ 29 30 int ed = lenb-lena; 31 LL ans = 0; 32 LL tmp = 0; 33 for(int i = 1;i <= lena;i++){ 34 if(a[i] == '0'){ 35 tmp = 1LL*(yi[ed+i]-yi[i-1]); 36 } 37 else { 38 tmp = 1LL*(ling[ed+i]-ling[i-1]); 39 } 40 ans += 1LL*tmp; 41 // printf("tmp = %I64d\n",tmp); 42 } 43 printf("%I64d\n",ans); 44 } 45 46 int main(){ 47 scanf("%s",a+1); 48 scanf("%s",b+1); 49 solve(); 50 }