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 }
时间: 2024-12-14 18:47:44