【codeforces 718 C&D】C. Sasha and Array&D. Andrew and Chemistry

            C. Sasha and Array

题目大意&题目链接:

  http://codeforces.com/problemset/problem/718/C

  长度为n的正整数数列,有m次操作,$opt==1$时,对$[L,R]$全部加x,$opt==2$时,对$[L,R]$求$\sum_{i=L}^{R}Fibonacc(a_{i})$。

 

题解:

  线段树+矩阵快速幂。

  在每个线段树存一个转移矩阵,然后YY即可。

代码:

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #define lc t<<1
  4 #define rc (t<<1)|1
  5 typedef long long ll;
  6 const int N=100100;
  7 const ll mod=(ll)1e9+7;
  8 inline int read(){
  9     int x=0,f=1;char ch=getchar();
 10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 12     return x*f;
 13 }
 14 struct Martrix{
 15     ll a[2][2];
 16     Martrix(){memset(a,0,sizeof(a));}
 17     inline void e(){
 18         memset(a,0,sizeof(a));
 19         for(int i=0;i<2;i++)
 20             a[i][i]=1;
 21     }
 22     inline void fibe(){
 23         for(int i=0;i<2;i++)
 24             for(int j=0;j<2;j++)
 25                 a[i][j]=1;
 26         a[1][1]=0;
 27     }
 28     friend Martrix operator *(Martrix x,Martrix y){
 29         Martrix z;
 30         for(int i=0;i<2;i++)
 31             for(int j=0;j<2;j++)
 32                 for(int k=0;k<2;k++)
 33                     z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
 34         return z;
 35     }
 36     friend Martrix operator ^(Martrix a,int b){
 37         Martrix ans;ans.e();
 38         while(b){
 39             if(b&1) ans=ans*a;
 40             b>>=1;
 41             a=a*a;
 42         }return ans;
 43     }
 44 }fibe_1;
 45 struct Tree{
 46     Martrix x,lazy;
 47 }tree[N<<2];
 48 const int root=1;
 49 inline void update(int t){
 50     tree[t].x.a[0][0]=(tree[lc].x.a[0][0]+tree[rc].x.a[0][0])%mod;
 51     tree[t].x.a[1][0]=(tree[lc].x.a[1][0]+tree[rc].x.a[1][0])%mod;
 52 }
 53 inline void downdate(int t){
 54     tree[lc].x=tree[t].lazy*tree[lc].x;
 55     tree[rc].x=tree[t].lazy*tree[rc].x;
 56     tree[lc].lazy=tree[lc].lazy*tree[t].lazy;
 57     tree[rc].lazy=tree[rc].lazy*tree[t].lazy;
 58     tree[t].lazy.e(); 
 59 }
 60 inline void build(int l,int r,int t){
 61     tree[t].lazy.e();
 62     if(l==r){
 63         int num=read()-1;
 64         tree[t].x.fibe();
 65         tree[t].x=(tree[t].x^num)*fibe_1;
 66         return ;
 67     }int mid=l+r>>1;
 68     build(l,mid,t<<1);build(mid+1,r,(t<<1)|1);
 69     update(t);
 70 }
 71 inline void add(int l,int r,int L,int R,int t,Martrix x){
 72     if(l!=r)
 73     downdate(t);
 74     if(L<=l&&r<=R){
 75         tree[t].x=x*tree[t].x;
 76         tree[t].lazy=x;
 77         return ;
 78     }
 79     int mid=l+r>>1;
 80     if(R>mid)   add(mid+1,r,L,R,rc,x);
 81     if(L<=mid)  add(l,mid,L,R,lc,x);
 82     update(t);
 83 }
 84 inline ll sum(int l,int r,int L,int R,int t){
 85     if(l!=r)
 86     downdate(t);
 87     if(L<=l&&r<=R){
 88         return tree[t].x.a[0][0];
 89     }
 90     int mid=l+r>>1;
 91     ll ans=0;
 92     if(R>mid)   ans+=sum(mid+1,r,L,R,rc);
 93     if(L<=mid)  ans+=sum(l,mid,L,R,lc);
 94     return ans%mod;
 95 }
 96 int n,m;
 97 int main(){
 98     n=read(),m=read();
 99     fibe_1.a[0][0]=1;
100     build(1,n,1);
101     for(int i=1,opt,l,r,x;i<=m;i++){
102         opt=read();
103         l=read(),r=read();
104         if(opt==1){
105             x=read();
106             Martrix now;now.fibe();
107             now=now^x;
108             add(1,n,l,r,root,now);
109         }
110         else{
111             printf("%lld\n",sum(1,n,l,r,root));
112         }
113     }
114 }

 

          D. Andrew and Chemistry

题目大意&链接:

  http://codeforces.com/problemset/problem/718/D

  (辣鸡有机化学)给一个无向图,每个节点只允许有至多4条边,且至少一条边,而且这个图是个树,现在新建一个节点,并与这个节点连条边,求可以构成多少个不一样的图(恩……就是是不是同构)。n<=100000

题解:

  写个靠谱的哈希……然后因为节点多,但是只会有最多4条边,设F[x][i]表示从第x个节点,走第i条边得到的hash值,如果已经得到F[x][i]就不要再dfs下去了。

  (什么你问我时间复杂度)

代码:

  

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<set>
 4 inline int read(){
 5     int s=0;char ch=getchar();
 6     while(ch<'0'||ch>'9')   ch=getchar();
 7     while(ch>='0'&&ch<='9') s=s*10+(ch^48),ch=getchar();
 8     return s;
 9 }
10 typedef unsigned long long ull;
11 ull P[6]={0u,76543u,233u,123457u,56741857u,1537427u};
12 const int N=100100;
13 ull f[N];
14 ull g[N][5];
15 std::set<ull> st;
16 int n;
17 struct edges {
18     int v;edges *last;
19 }edge[N<<1],*head[N];int cnt;
20 inline void push(int u,int v){
21     edge[++cnt]=(edges){v,head[u]};head[u]=edge+cnt;
22 }
23 int a[5];
24 inline bool cmp(int x,int y){
25     return f[x]<f[y];
26 }
27 inline void dfs(int x,int fa){
28     int num=0;
29     f[x]=1u;
30     int k=0;
31     for(edges *i=head[x];i;i=i->last){
32         k++;
33         if(fa==i->v)    continue;
34         if(!g[x][k]) 
35         dfs(i->v,x),g[x][k]=f[i->v];
36         else
37         f[i->v]=g[x][k];
38     }
39     for(edges *i=head[x];i;i=i->last)
40         if(fa==i->v)    continue;
41         else    a[++num]=i->v;
42     std::sort(a+1,a+1+num,cmp);
43     for(int i=1;i<=num;i++)
44         f[x]=f[x]*P[5]+f[a[i]]*P[i];
45 }
46 int red[N];
47 int main(){
48     n=read();
49     for(int i=1;i<n;i++){
50         int u=read(),v=read();
51         push(u,v);push(v,u);
52         red[u]++,red[v]++;
53     }
54     //printf("s");
55     for(int i=1;i<=n;i++){//printf("i=%d\n",i);
56         if(red[i]<4){
57             dfs(i,i);
58            // printf("i=%d\n",i);
59             st.insert(f[i]);         
60         }
61     }
62     printf("%d\n",st.size());
63 }

 

 

 

posted @ 2017-09-12 21:29  Troywar  阅读(239)  评论(0编辑  收藏  举报