SD的题有点反人类啊。。。
d1t1[SDOI2018]物理实验
感觉比较好想但不太好写,写了一半弃了
d1t2[SDOI2018]战略游戏
建出圆方树,每次建虚树,答案就是虚树上的原点个数减去询问的点数。
1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #include<set> 11 #include<map> 12 #define For(i,a,b) for(int i=(a);i<=(b);i++) 13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--) 14 const int N=4e5+7; 15 typedef long long LL; 16 typedef double db; 17 using namespace std; 18 int cas,n,m,Q,tot; 19 20 template<typename T> void read(T &x) { 21 char ch=getchar(); x=0; T f=1; 22 while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar(); 23 if(ch==‘-‘) f=-1,ch=getchar(); 24 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; x*=f; 25 } 26 27 struct graph { 28 int ecnt,fir[N],nxt[N],to[N],v[N],dfn[N],dfs_clock,f[N][20],R[N],sz[N]; 29 30 void init() { 31 memset(fir,0,sizeof(fir)); 32 memset(v,0,sizeof(v)); 33 ecnt=0; For(i,1,n) v[i]=1; 34 } 35 36 int in(int y,int x) { return dfn[y]>=dfn[x]&&dfn[y]<dfn[x]+sz[x]; } 37 38 void add(int u,int v) { 39 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; 40 } 41 42 void dfs(int x,int fa) { 43 sz[x]=1; 44 f[x][0]=fa; 45 v[x]+=v[fa]; 46 R[x]=R[fa]+1; 47 dfn[x]=++dfs_clock; 48 For(i,1,18) f[x][i]=f[f[x][i-1]][i-1]; 49 for(int i=fir[x];i;i=nxt[i]) { 50 dfs(to[i],x); 51 sz[x]+=sz[to[i]]; 52 } 53 } 54 55 int lca(int x,int y) { 56 if(R[x]<R[y]) swap(x,y); 57 Rep(i,18,0) if(R[f[x][i]]>=R[y]) 58 x=f[x][i]; 59 if(x==y) return x; 60 Rep(i,18,0) if(f[x][i]!=f[y][i]) 61 x=f[x][i],y=f[y][i]; 62 return f[x][0]; 63 } 64 65 }G; 66 67 struct Tarjan { 68 int dfn[N],low[N],dfs_clock,rr,sta[N],top; 69 int ecnt,fir[N],nxt[N],to[N]; 70 71 void init() { 72 memset(fir,0,sizeof(fir)); 73 memset(dfn,0,sizeof(dfn)); 74 ecnt=1; dfs_clock=0; top=0; tot=n; 75 } 76 77 void add(int u,int v) { 78 nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; 79 nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; 80 } 81 82 void tarjan(int x,int F) { 83 dfn[x]=low[x]=++dfs_clock; 84 for(int i=fir[x];i;i=nxt[i]) { 85 if(i==(F^1)) continue; 86 if(!dfn[to[i]]) { 87 sta[++top]=i; 88 tarjan(to[i],i); 89 if(low[to[i]]>=dfn[x]) { 90 G.add(x,++tot); 91 while(top) { 92 int j=sta[top--]; 93 G.add(tot,to[j]); 94 if(j==i) break; 95 } 96 } 97 low[x]=min(low[x],low[to[i]]); 98 } 99 else low[x]=min(low[x],dfn[to[i]]); 100 } 101 } 102 }T; 103 104 bool cmp(const int &A,const int&B) { return G.dfn[A]<G.dfn[B]; } 105 106 struct work { 107 int q[N],sta[N],top; 108 void sol() { 109 read(n); read(m); 110 G.init(); T.init(); 111 For(i,1,m) { 112 int u,v; 113 read(u); read(v); 114 T.add(u,v); 115 } 116 T.tarjan(1,0); 117 G.dfs(1,0); 118 read(Q); 119 while(Q--) { 120 int c; top=0; 121 read(c); q[0]=c; 122 For(i,1,c) read(q[i]); 123 sort(q+1,q+c+1,cmp); 124 For(i,1,c-1) q[++q[0]]=G.lca(q[i],q[i+1]); 125 sort(q+1,q+q[0]+1,cmp); 126 int sz=unique(q+1,q+q[0]+1)-(q+1); 127 int ans=q[1]<=n; 128 For(i,1,sz) { 129 while(top&&!G.in(q[i],q[sta[top]])) top--; 130 if(top) { ans+=G.v[q[i]]-G.v[q[sta[top]]]; } 131 sta[++top]=i; 132 } 133 printf("%d\n",ans-c); 134 } 135 } 136 }W; 137 138 //#define DEBUG 139 int main() { 140 #ifdef DEBUG 141 freopen("1.in","r",stdin); 142 //freopen(".out","w",stdout); 143 #endif 144 read(cas); 145 while(cas--) W.sol(); 146 return 0; 147 }
d1t3[SDOI2018]反回文串
我觉得有点神啊。。。
要用O(1)快速乘,不然会T成55分。
如果质因子的数组没开LL,会卡死在91分。。
如果抄了luogu题解里的O(1)快速乘,没有对结果取模,94分。。
1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #include<set> 11 #include<map> 12 #define For(i,a,b) for(LL i=(a);i<=(b);i++) 13 #define Rep(i,a,b) for(LL i=(a);i>=(b);i--) 14 const int N=1e5+7; 15 typedef long long LL; 16 typedef long double LD; 17 typedef double db; 18 using namespace std; 19 LL T; 20 LL n,k,p,q[N],lq[N],cq[N]; 21 22 template<typename T> void read(T &x) { 23 char ch=getchar(); x=0; T f=1; 24 while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar(); 25 if(ch==‘-‘) f=-1,ch=getchar(); 26 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; x*=f; 27 } 28 29 LL ksc(LL a,LL b,LL p) { 30 /*a%=p; b%=p; 31 LL rs=0,bs=a; 32 while(b) { 33 if(b&1) rs=(rs+bs)%p; 34 bs=(bs+bs)%p; 35 b>>=1; 36 } 37 return rs;*/ 38 LL tp=a*b-(LL)((LD)a/p*b+1.0e-8)*p; 39 return tp<0?tp+p:tp%p; 40 } 41 42 LL tp=a*b-(LL)((LD)a/p*b+1.0e-8)*p; 43 44 LL ksm(LL a,LL b,LL p) { 45 LL rs=1,bs=a%p; 46 while(b) { 47 if(b&1) rs=ksc(rs,bs,p); 48 bs=ksc(bs,bs,p); 49 b>>=1; 50 } 51 return rs; 52 } 53 54 int miller_rabin(LL n) { 55 if(n==1||n==2||n==3||n==5||n==7||n==11) return 1; 56 if(!(n%2)||!(n%3)||!(n%5)||!(n%7)||!(n%11)) return 0; 57 LL u=n-1,k=0; 58 while(!(u&1)) { u>>=1; k++; } 59 For(ti,1,15) { 60 LL a=rand()%(n-2)+2; 61 LL x=ksm(a,u,n),y; 62 For(i,1,k) { 63 y=ksc(x,x,n); 64 if(y==1&&x!=1&&x!=n-1) return 0; 65 x=y; 66 } 67 if(x!=1) return 0; 68 } 69 return 1; 70 } 71 72 LL gcd(LL a,LL b) { return !b?a:gcd(b,a%b); } 73 74 LL pollard_rho(LL n,LL c) { 75 LL x=rand()%n,y=x; 76 for(LL i=2,k=2;;i++) { 77 x=(ksc(x,x,n)+c)%n; 78 LL tp=gcd(n,(x-y+n)%n); 79 if(tp>1&&tp<n) return tp; 80 if(x==y) return n; 81 if(i==k) k+=k,y=x; 82 } 83 } 84 85 void find(LL n) { 86 if(miller_rabin(n)) { 87 q[++q[0]]=n; 88 return ; 89 } 90 LL tp=n; 91 for(LL c=13;;c++) { 92 tp=pollard_rho(n,c); 93 if(tp>1&&tp<n) break; 94 } 95 find(tp); find(n/tp); 96 } 97 98 LL F(LL d) { return ksm(k,((d&1)?d/2+1:d/2),p); } 99 LL h(LL d) { return (d&1)?d%p:d/2%p; } 100 101 LL ans; 102 void dfs(int pos,int up,LL now,LL tt) { 103 if(pos==up+1) { 104 LL d=n/now; 105 if((d&1)&&!(now&1)) ; 106 else ans=(ans+F(d)*h(d)%p*tt%p)%p; return; 107 } 108 For(i,0,cq[pos]) { 109 dfs(pos+1,up,now,i?(1-lq[pos]%p+p)%p*tt%p:tt); 110 now*=lq[pos]; 111 } 112 } 113 114 void solve() { 115 sort(q+1,q+q[0]+1); lq[0]=0; 116 For(i,1,q[0]) { 117 if(i==1||q[i]!=q[i-1]) { lq[++lq[0]]=q[i]; cq[lq[0]]=1; } 118 else cq[lq[0]]++; 119 } 120 ans=0; dfs(1,lq[0],1,1); 121 printf("%lld\n",ans); 122 } 123 124 //#define DEBUG 125 int main() { 126 #ifdef DEBUG 127 freopen("1.in","r",stdin); 128 //freopen(".out","w",stdout); 129 #endif 130 srand(998244353); 131 read(T); 132 while(T--) { 133 read(n); read(k); read(p); 134 q[0]=0; find(n); 135 solve(); 136 } 137 return 0; 138 }
d2t1[SDOI2018]原题识别
什么神题啊。。。
感觉前30分可以树上莫队,中间30分可以树套树搞一下。
正解好神啊,不会啊,等我什么时候学会了来补吧。
d2t2[SDOI2018]旧试题
题解超详细的。
也好神啊。
听说很卡常,大常数选手不敢写。。
d2t3[SDOI2018]荣誉称号
全场最简单的一道题。
转化为二叉树,限制变成树上任意一条长度为k+1的链的和mod m==0
发现要满足要求,则i*2^(k+1)和i在mod m意义下同余。
于是可以拿前2^k-1个点dp,在每个点处计算它和它下面和它同余的所有点的代价和。
这个代价可以算出第一个然后预处理出b的前缀和来快速转移。
然后就可以2^k*m^2的dp转移了。
1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include<cmath> 10 #include<set> 11 #include<map> 12 #define For(i,a,b) for(int i=(a);i<=(b);i++) 13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--) 14 const int N=2e7+7; 15 typedef long long LL; 16 typedef double db; 17 using namespace std; 18 int T,n,k,m,a[N],b[N],sta[N],top; 19 20 template<typename T> void read(T &x) { 21 char ch=getchar(); x=0; T f=1; 22 while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar(); 23 if(ch==‘-‘) f=-1,ch=getchar(); 24 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; x*=f; 25 } 26 27 unsigned int SA, SB, SC;int p, A, B; 28 unsigned int rng61(){ 29 SA ^= SA << 16; 30 SA ^= SA >> 5; 31 SA ^= SA << 1; 32 unsigned int t = SA; 33 SA = SB; 34 SB = SC; 35 SC ^= t ^ SA; 36 return SC; 37 } 38 void gen(){ 39 scanf("%d%d%d%d%u%u%u%d%d", &n, &k, &m, &p, &SA, &SB, &SC, &A, &B); 40 for(int i = 1; i <= p; i++)scanf("%d%d", &a[i], &b[i]); 41 for(int i = p + 1; i <= n; i++){ 42 a[i] = rng61() % A + 1; 43 b[i] = rng61() % B + 1; 44 } 45 } 46 47 bool cmp(const int &A,const int &B) { 48 return a[A]<a[B]; 49 } 50 51 LL dp[4149][207],t[207],c[207]; 52 void solve() { 53 LL ans=0; 54 For(i,1,n) a[i]%=m; 55 memset(dp,127,sizeof(dp)); 56 Rep(i,(1<<k+1)-1,1) { 57 memset(t,0,sizeof(t)); 58 memset(c,0,sizeof(c)); 59 top=0; 60 for(LL pos=i,bs=1;pos<=n;pos*=(1<<k+1),bs*=(1<<k+1)) { 61 for(int l=pos;l/bs==i;l++) { 62 sta[++top]=l; c[a[l]]+=b[l]; 63 } 64 } 65 For(j,0,m-1) c[j]+=c[j-1]; 66 For(j,0,m-1) { 67 if(j==0) For(k,1,top) t[j]+=(a[sta[k]]<=j?j-a[sta[k]]:m-(a[sta[k]]-j))*b[sta[k]]; 68 else t[j]=t[j-1]+c[j-1]-(m-1)*(c[j]-c[j-1])+(c[m-1]-c[j]); 69 } 70 if(i>=(1<<k)) { 71 For(j,0,m-1) dp[i][j]=t[j]; 72 } 73 else { 74 For(j,0,m-1) For(k,0,m-1) { 75 LL tp=dp[i<<1][j]+dp[(i<<1)|1][j]; 76 dp[i][(j+k)%m]=min(dp[i][(j+k)%m],tp+t[k]); 77 } 78 } 79 } 80 printf("%lld\n",dp[1][0]); 81 } 82 83 //#define DEBUG 84 int main() { 85 #ifdef DEBUG 86 freopen("1.in","r",stdin); 87 //freopen(".out","w",stdout); 88 #endif 89 read(T); 90 while(T--) { 91 gen(); 92 solve(); 93 } 94 return 0; 95 }
原文地址:https://www.cnblogs.com/Achenchen/p/9077817.html
时间: 2024-08-30 15:51:35