Codeforces Round #179 (Div. 1)

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 }
View Code

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 }
View Code

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<<"\n"<<dp[1][c1][c2]<<endl;

75     else

76     printf("-1\n0\n");

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 }
View Code

 

你可能感兴趣的:(codeforces)