标签:模拟 hide lag 复杂 targe last 结构 情况 void
这里记录一下我 已经复习过的东西了 这次玩脱了 可就真的 回去了 要再认真一点。
第一个知识点:点双联通分量
先来一个点双联通分量 这几天 有模拟赛考这个了 但是我不太会写,qwq.类似于强连通分量的那种东西不过栈里要一直存一个割点。
值得一提的是 我把点双写成边双 写错好多次了这次下次一定不能错要分清什么时候点双什么时候边双。
LINK:牛客day2T2 点双
//#include<bits/stdc++.h> #include<iostream> #include<queue> #include<iomanip> #include<cctype> #include<cstdio> #include<deque> #include<utility> #include<cmath> #include<ctime> #include<cstring> #include<string> #include<cstdlib> #include<vector> #include<algorithm> #include<stack> #include<map> #include<set> #include<bitset> #define INF 1000000000 #define ll long long #define db double #define pb push_back #define un unsigned #define mod 1000000007 #define ull unsigned long long using namespace std; char *fs,*ft,buf[1<<15]; inline char getc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline int read() { int x=0,f=1;char ch=getc(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getc();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getc();} return x*f; } //满堂花醉三千客 一剑霜寒十四州. const int MAXN=1000010; int n,m,k; int top,cnt,ans,rt,id,w,len=1; int q[MAXN]; int s[MAXN]; int dfn[MAXN],low[MAXN],vis[MAXN]; int lin[MAXN],ver[MAXN<<2],nex[MAXN<<2]; inline int cmp(int x,int y){return x>y;} inline void add(int x,int y) { ver[++len]=y; nex[len]=lin[x]; lin[x]=len; } inline void dfs(int x) { dfn[x]=low[x]=++cnt; s[++top]=x; for(int i=lin[x];i;i=nex[i]) { int tn=ver[i]; if(!dfn[tn]) { dfs(tn); low[x]=min(low[x],low[tn]); if(low[tn]==dfn[x]) { int sz=0; for(int j;j!=tn;--top) { j=s[top]; ++sz; } ++sz; if(sz==2){if(k)--k,++ans;} else q[++id]=sz; } } else low[x]=min(low[x],dfn[tn]); } } int main() { //freopen("1.in","r",stdin); n=read();m=read();k=read(); for(int i=1;i<=m;++i) { int x,y; x=read();y=read(); add(x,y);add(y,x); } for(int i=1;i<=n;++i) if(!dfn[i]) { ++ans;top=0; dfs(i); } sort(q+1,q+1+id,cmp); for(int i=1;i<=id;++i) { if(!k)break; --k; w=min(k,q[i]-1); ans+=w; k-=w; } printf("%d\n",ans); return 0; }
第二个知识点:欧拉降幂
欧拉降幂又又又忘了 真服了自己了 什么都忘。首先 进行欧拉降幂 线性筛得会吧 其实原理就是用最小的质因数去筛没什么。
然后 需要注意的是 暴力不断降幂的复杂度是logn的或者2logn的,证明其还是很显然的。
值得一提的是 降到1返回0 没降到边界到了直接快速幂搞定即可。配合上 快速幂或者gcd 复杂度就到了log方了。
一定注意开long long。
LINK:黄金妖精奈芙莲 欧拉降幂模板题
!!!高能预警 wa掉了 少考虑了一个东西 扩展欧拉定理的适用条件是 b>=phi(n) 然后才能 搞少考虑了情况 上次好像也是这个地方wa 下次不能再wa了。
考虑怎么改我们是必要知道后面的取值才能知道前面到底是否取模 一个比较简明的方法是 开结构体一个保存是否大于phi(n)一个保存在大于的情况下的结果。(这个做法我并不认可 想了40min 正确性有问题。或者说不严谨。
还是考虑一种慢一点的 但是比较没有争议的做法吧。我们直接暴力到在后面找几项暴力计算 由于>1的指数幂增长非常快(就算都是2也大于int了 所以是觉得正确的 但是这样的方法可以判定总体复杂度也就多加一点点。
出了点小bug 不过没关系 又仔细复习了一遍。复杂度还是log^2的 不过多一个常数(也就慢5倍吧/cy
//#include<bits/stdc++.h> #include<iostream> #include<queue> #include<iomanip> #include<cctype> #include<cstdio> #include<deque> #include<utility> #include<cmath> #include<ctime> #include<cstring> #include<string> #include<cstdlib> #include<vector> #include<algorithm> #include<stack> #include<map> #include<set> #include<bitset> #define INF 1000000000 #define ll long long #define db double #define pb push_back #define un unsigned #define ull unsigned long long using namespace std; char *fs,*ft,buf[1<<15]; inline char getc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline int read() { int x=0,f=1;char ch=getc(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getc();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getc();} return x*f; } const int MAXN=500010,maxn=20000010; int top,n,m,maxx=20000000,mark; ll a[MAXN],c[MAXN],b[MAXN]; int phi[maxn],v[maxn],p[maxn]; inline void add(int x,ll y) { while(x<=n) { c[x]+=y; x+=x&(-x); } } inline ll ask(int x) { ll ans=0; while(x) { ans+=c[x]; x-=x&(-x); } return ans; } inline ll ksm(ll b,ll p,ll mod) { ll ans=1; while(p) { if(p&1)ans=ans*b%mod; b=b*b%mod; p=p>>1; } return ans; } inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll fast_pow(ll b,ll p,ll mod) { ll ans=1; while(p) { if(b>=mod) { mark=1; return 1; } if(p&1)ans=ans*b; if(ans>=mod) { mark=1; return 1; } b=b*b; p=p>>1; } return ans; } inline ll dfs(int l,int r,int x) { if(x==1)return 0; int w=(a[l]+ask(l))%x;//当前数字 if(w==1)return 1; if(l==r)return w; ll res=0; int flag=gcd(w,x)==1?0:1; int last=min(l+6,r); for(int i=last;i>l;--i) { b[i]=a[i]+ask(i); if(b[i]==1)last=i; } int ww=1;mark=0; for(int i=last;i>l;--i) { ww=fast_pow(b[i],ww,phi[x]); if(mark)break; } if(mark)res=dfs(l+1,r,phi[x])+flag*phi[x]; else res=dfs(l+1,r,x); return ksm(w,res,x); } int main() { //freopen("1.in","r",stdin); n=read();m=read(); for(int i=1;i<=n;++i)a[i]=read(); for(int i=2;i<=maxx;++i) { if(!phi[i]) { p[++top]=i; phi[i]=i-1; v[i]=i; } for(int j=1;j<=top;++j) { if(p[j]>v[i]||i>maxx/p[j])break; v[i*p[j]]=p[j]; phi[i*p[j]]=i%p[j]?phi[i]*(p[j]-1):phi[i]*p[j]; } } for(int i=1;i<=m;++i) { int op,l,r,x; op=read();l=read();r=read();x=read(); if(op==1)add(l,x),add(r+1,-x); else printf("%lld\n",dfs(l,r,x)); } return 0; }
标签:模拟 hide lag 复杂 targe last 结构 情况 void
原文地址:https://www.cnblogs.com/chdy/p/11790269.html