A 直接线段树过的 两遍 貌似大多是标记过的。。注意long long
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #include <queue> 6 #include <algorithm> 7 using namespace std; 8 #define LL long long 9 #define N 100100 10 LL s[N<<2],lz[N<<2],st[N<<2],lzt[N<<2]; 11 LL a[N]; 12 struct node 13 { 14 int l,r; 15 LL d; 16 }p[N]; 17 void build(int l,int r,int w) 18 { 19 if(l==r) 20 { 21 st[w] = a[l]; 22 return; 23 } 24 int m = (l+r)>>1; 25 build(l,m,w<<1); 26 build(m+1,r,w<<1|1); 27 } 28 void down(int w,int m,int f) 29 { 30 if(f) 31 { 32 if(lz[w]) 33 { 34 s[w<<1]+=lz[w]*(m-m/2); 35 s[w<<1|1]+=lz[w]*(m/2); 36 lz[w<<1] +=lz[w]; 37 lz[w<<1|1]+=lz[w]; 38 lz[w] = 0; 39 } 40 } 41 else 42 { 43 if(lzt[w]) 44 { 45 st[w<<1]+=lzt[w]*(m-m/2); 46 st[w<<1|1]+=lzt[w]*(m/2); 47 lzt[w<<1] += lzt[w]; 48 lzt[w<<1|1] += lzt[w]; 49 lzt[w] = 0; 50 } 51 } 52 } 53 void update(int a,int b,LL d,int l,int r,int w,int f) 54 { 55 if(a<=l&&b>=r) 56 { 57 if(f) 58 { 59 s[w]+=(r-l+1); 60 lz[w]++; 61 } 62 else 63 { 64 st[w]+=(r-l+1)*d; 65 lzt[w]+=d; 66 } 67 return ; 68 } 69 down(w,r-l+1,f); 70 int m = (l+r)>>1; 71 if(a<=m) 72 update(a,b,d,l,m,w<<1,f); 73 if(b>m) 74 update(a,b,d,m+1,r,w<<1|1,f); 75 } 76 LL query(int p,int l,int r,int w,int f) 77 { 78 if(l==r) 79 { 80 if(f) 81 return s[w]; 82 else return st[w]; 83 } 84 down(w,r-l+1,f); 85 int m = (l+r)>>1; 86 if(p<=m) 87 return query(p,l,m,w<<1,f); 88 else return query(p,m+1,r,w<<1|1,f); 89 } 90 int main() 91 { 92 int i,k,n,m; 93 cin>>n>>m>>k; 94 for(i = 1 ; i <= n ;i++) 95 cin>>a[i]; 96 build(1,n,1); 97 for(i = 1; i <= m ;i++) 98 cin>>p[i].l>>p[i].r>>p[i].d; 99 while(k--) 100 { 101 int x,y; 102 cin>>x>>y; 103 update(x,y,1,1,m,1,1); 104 } 105 for(i = 1; i <= m ; i++) 106 { 107 p[i].d = query(i,1,m,1,1)*p[i].d; 108 if(p[i].d) 109 { 110 update(p[i].l,p[i].r,p[i].d,1,n,1,0); 111 } 112 } 113 for(i = 1; i < n ;i++) 114 { 115 cout<<query(i,1,n,1,0)<<" "; 116 } 117 cout<<query(n,1,n,1,0)<<endl; 118 return 0; 119 }
B floyd的变形 倒着更新 每次加一个节点 然后利用floyd的dp性质对所有的点对距离进行更新
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #include <queue> 6 #include <algorithm> 7 using namespace std; 8 #define N 510 9 #define LL long long 10 int a[N][N],b[N],q[N]; 11 LL w[N][N],s[N]; 12 int main() 13 { 14 int i,j,n,e; 15 cin>>n; 16 for(i = 1; i <= n ;i++) 17 { 18 for(j = 1; j <= n ;j++) 19 { 20 cin>>a[i][j]; 21 w[i][j] = a[i][j]; 22 } 23 } 24 for(i = 1 ; i <= n ;i++) 25 { 26 cin>>b[i]; 27 } 28 int g = 0; 29 for(i = n ; i>=1 ; i--) 30 { 31 LL ans=0; 32 g++; 33 q[g] = b[i]; 34 for(j = 1; j <= n ;j++) 35 for(e = 1; e <= n ;e++) 36 w[j][e] = min(w[j][b[i]]+w[b[i]][e],w[j][e]); 37 for(j = 1; j <= g ; j++) 38 for(e = 1; e <= g ; e++) 39 { 40 //w[q[j]][q[e]] = min(w[q[j]][b[i]]+w[b[i]][q[e]],w[q[j]][q[e]]); 41 ans+=w[q[j]][q[e]]; 42 } 43 s[i] = ans; 44 } 45 for(i = 1; i <= n ; i++) 46 cout<<s[i]<<" "; 47 return 0; 48 }
C 搜索+dp
刚开始只往 dp方向 想了 想着先dp出最短的 再倒 回去符合情况的状态保存下来 找次数 貌似时间复杂度 以及代码难写度都很高 正确性也不能保证。。果断没写
看了题解说是搜索+dp 想到用bfs保存状态求次数最小 貌似遇到组合就会卡 组合求 次数的地方一直没写对 之后参考别人的 应该是每次符合情况的都要加上而不只是入队的那颗加 挺好的一题
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stdlib.h> 5 #include<vector> 6 #include<queue> 7 #include<stack> 8 #include<cmath> 9 using namespace std; 10 #define LL long long 11 #define mod 1000000007 12 #define INF 0xfffffff 13 LL c[55][55]; 14 int vis[2][55][55]; 15 LL dp[2][55][55]; 16 struct node 17 { 18 int num,a,b,d; 19 }; 20 int n,k; 21 void init() 22 { 23 int i,j; 24 for(i = 0; i <= n ;i++) 25 { 26 c[i][0] = 1; 27 } 28 for(i = 1 ; i <= n; i++) 29 { 30 for(j = 1 ; j <= i ; j++) 31 { 32 c[i][j] = (c[i-1][j]+c[i-1][j-1])%mod; 33 } 34 } 35 } 36 void bfs(int c1,int c2) 37 { 38 int i,j; 39 queue<node>q; 40 node tt; 41 memset(vis,-1,sizeof(vis)); 42 tt.num = 0;tt.d = 0; 43 tt.a = c1;tt.b = c2; 44 vis[0][c1][c2] = 0; 45 dp[0][c1][c2] = 1; 46 q.push(tt); 47 int minz = INF; 48 while(!q.empty()) 49 { 50 node st = q.front();q.pop(); 51 if(st.a==c1&&st.b==c2&&st.d==1) minz = min(minz,st.num); 52 for(i = 0; i <= st.a ; i++) 53 for(j = 0 ; j <= st.b ; j++) 54 { 55 int a1 = c1-st.a+i; 56 int b1 = c2-st.b+j; 57 if(i+j>=1&&i*50+j*100<=k) 58 { 59 if(vis[st.d^1][a1][b1]==-1) 60 { 61 vis[st.d^1][a1][b1] = vis[st.d][st.a][st.b]+1; 62 tt.num = st.num+1; 63 tt.a = a1;tt.b = b1; 64 tt.d = st.d^1; 65 q.push(tt); 66 dp[st.d^1][a1][b1] = (dp[st.d^1][a1][b1]+((dp[st.d][st.a][st.b]*c[st.a][i])%mod*c[st.b][j])%mod)%mod; 67 } 68 else if(vis[st.d^1][a1][b1]==vis[st.d][st.a][st.b]+1) 69 dp[st.d^1][a1][b1] = (dp[st.d^1][a1][b1]+((dp[st.d][st.a][st.b]*c[st.a][i])%mod*c[st.b][j])%mod)%mod; 70 } 71 } 72 } 73 if(minz!=INF) 74 cout<<minz<<" "<<dp[1][c1][c2]<<endl; 75 else 76 printf("-1 0 "); 77 } 78 int main() 79 { 80 int i; 81 cin>>n>>k;init(); 82 int c1=0,c2=0; 83 for(i = 1; i <= n ;i++) 84 { 85 int a; 86 cin>>a; 87 if(a==50) 88 c1++; 89 else c2++; 90 } 91 bfs(c1,c2); 92 return 0; 93 }