zoukankan      html  css  js  c++  java
  • 20191102 「HZOJ NOIP2019 Round #12」20191102模拟

    先开坑。

    md原题写挂我也真是。。。

    100+20+10


    白夜

    打表大法吼

    显然,不在环上的点对答案的贡献是 ((k-cycle)^{k-1})

    打表得到环上的递推式,矩阵一下乘起来就好了。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    template <typename Tp>
    void read(Tp &x){
    	x=0;char ch=1;int fh;
    	while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    	if(ch=='-') ch=getchar(),fh=-1;
    	else fh=1;
    	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	x*=fh;
    }
    
    const int maxn=100007;
    const int maxm=200007;
    const int mod=998244353;
    
    int n,T;
    int Head[maxn],to[maxm],Next[maxm],tot=1;
    int aa,bb,k;
    bool vis[maxn];
    int col[maxn];
    
    int size[maxn],top[maxn],dep[maxn],fa[maxn];
    int son[maxn];
    
    void add(int x,int y){
    	to[++tot]=y,Next[tot]=Head[x],Head[x]=tot;
    }
    
    namespace baoli{
    	bool check(int x){
    		vis[x]=1;
    		for(int i=Head[x];i;i=Next[i]){
    			int y=to[i];
    			if(col[y]==col[x]) return false;
    			if(vis[y]) continue;
    			bool tmp=check(y);
    			if(tmp==false) return false;
    		}
    		if(x==aa){
    			if(col[aa]==col[bb]) return false;
    			if(!vis[bb]){
    				bool tmp=check(bb);
    				if(tmp==false) return false;
    			}
    		}
    		if(x==bb){
    			if(col[aa]==col[bb]) return false;
    			if(!vis[aa]){
    				bool tmp=check(aa);
    				if(tmp==false) return false;
    			}
    		}
    		return true;
    	}
    	int dfs(int step){
    		if(step==n+1){
    			memset(vis,0,sizeof(vis));
    			if(check(1)) return 1;
    			else return 0;
    		}
    		int res=0;
    		for(int i=1;i<=k;i++){
    			col[step]=i;
    			res=(res+dfs(step+1))%mod;
    		}
    		return res;
    	}
    	void MAIN(){
    		while(T--){
    			read(aa);read(bb);read(k);
    			if(k==1&&n!=1){
    				puts("0");continue;
    			}
    			printf("%lld
    ",dfs(1));
    		}
    	}
    }
    
    namespace Try{
    	struct Matrix{
    		int mat[4][4],n;
    		Matrix(){
    			memset(mat,0,sizeof(mat));
    			n=2;
    		}
    		void reset(){
    			for(int i=1;i<=n;i++) mat[i][i]=1;
    		}
    	};
    	Matrix Mul(Matrix a,Matrix b){
    		Matrix c;c.n=a.n;
    		int l=a.n;
    		for(int i=1;i<=l;i++){
    			for(int j=1;j<=l;j++){
    				for(int k=1;k<=l;k++){
    					c.mat[i][j]+=(a.mat[i][k]*b.mat[k][j]%mod);
    					c.mat[i][j]%=mod;
    				}
    			}
    		}
    		return c;
    	}
    	Matrix fpow(Matrix x,int p){
    		Matrix res;res.reset();
    		while(p){
    			if(p&1) res=Mul(res,x);p>>=1;
    			x=Mul(x,x);
    		}
    		return res;
    	}
    	int ksm(int x,int p){
    		int res=1;
    		while(p){
    			if(p&1) res=res*x%mod;p>>=1;
    			x=x*x%mod;
    		}
    		return res;
    	}
    	void dfs1(int x,int f,int dp){
    		dep[x]=dp,fa[x]=f,size[x]=1;
    		int mx=-1;
    		for(int i=Head[x];i;i=Next[i]){
    			int y=to[i];
    			if(y==f) continue;
    			dfs1(y,x,dp+1);
    			size[x]+=size[y];
    			if(size[y]>mx) son[x]=y,mx=size[y];
    		}
    	}
    	void dfs2(int x,int tp){
    		top[x]=tp;
    		if(!son[x]) return;
    		dfs2(son[x],tp);
    		for(int i=Head[x];i;i=Next[i]){
    			int y=to[i];
    			if(y==son[x]||y==fa[x]) continue;
    			dfs2(y,y);
    		}
    	}
    	int lca(int x,int y){
    		while(top[x]!=top[y]){
    			if(dep[top[x]]<dep[top[y]]) swap(x,y);
    			x=fa[top[x]];
    		}
    		if(dep[x]>dep[y]) swap(x,y);
    		return x;
    	}
    	int calc(int cyc){
    		if(cyc==1) return 0;
    		if(cyc==2){
    			return k*(k-1)%mod;
    		}
    		Matrix base,ans;
    		base.mat[1][1]=k-2,base.mat[1][2]=k-1,base.mat[2][1]=1;
    		ans.mat[1][1]=k*(k-1)%mod;
    		ans=Mul(ans,fpow(base,cyc-2));
    		return ans.mat[1][1];
    	}
    	void MAIN(){
    		dfs1(1,0,1);dfs2(1,1);
    		int x,y,ans=0;
    		while(T--){
    			read(x);read(y);read(k);
    			int lc=lca(x,y);int cyc=dep[x]+dep[y]-2*dep[lc]+1;
    			ans=ksm(k-1,n-cyc);
    			ans=(ans*calc(cyc))%mod;
    			printf("%lld
    ",ans);
    		}
    	}
    }
    
    signed main(){
    	freopen("night.in","r",stdin);freopen("night.out","w",stdout);
    	read(n);
    	for(int x,i=2;i<=n;i++){
    		read(x);
    		add(x,i);add(i,x);
    	}
    	read(T);
    	Try::MAIN();
    	fclose(stdin);fclose(stdout);
    	return 0;
    }
    

    光明

    区间最大字段和

    GSS系列

    样例太弱了...

    这题被 (O(n^2)) 氧化钙过去了。。。

    订正后代码:

    using namespace std;
    
    template <typename Tp>
    void read(Tp &x){
    	x=0;char ch=1;int fh;
    	while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    	if(ch=='-') ch=getchar(),fh=-1;
    	else fh=1;
    	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	x*=fh;
    }
    
    const int maxn=100007;
    
    int n,T;
    int w[maxn];
    int xx[maxn],yy[maxn];
    #define lfc (x<<1)
    #define rgc ((x<<1)|1)
    #define mid ((l+r)>>1)
    
    struct node{
    	int sum,lf,rg,val;
    };
    
    int sum[maxn<<2],val[maxn<<2],rg[maxn<<2],lf[maxn<<2];
    
    void pushup(int x){
    	sum[x]=sum[lfc]+sum[rgc];
    	lf[x]=max(lf[lfc],sum[lfc]+lf[rgc]);
    	rg[x]=max(rg[rgc],sum[rgc]+rg[lfc]);
    	val[x]=max(max(val[lfc],val[rgc]),lf[rgc]+rg[lfc]);
    }
    
    void build(int x,int l,int r){
    	if(l==r){
    		int fff=1;
    		if(xx[l]%2==1&&yy[l]%2==1) fff=-1;
    		val[x]=sum[x]=lf[x]=rg[x]=fff*w[l];return;
    	}
    	build(lfc,l,mid);build(rgc,mid+1,r);
    	pushup(x);
    }
    
    int L,R,need;
    
    node query(int x,int l,int r){
    	if(L<=l&&r<=R) return (node){sum[x],lf[x],rg[x],val[x]};
    	if(L>mid) return query(rgc,mid+1,r);
    	if(R<=mid) return query(lfc,l,mid);
    	node res,a1=query(lfc,l,mid),a2=query(rgc,mid+1,r);
    	res.sum=a1.sum+a2.sum;
    	res.lf=max(a1.lf,a1.sum+a2.lf);
    	res.rg=max(a2.rg,a1.rg+a2.sum);
    	res.val=max(max(a1.val,a2.val),a1.rg+a2.lf);
    	return res;
    }
    
    void change_val(int x,int l,int r){
    	if(l==r){
    		int fff=1;
    		if(xx[l]%2==1&&yy[l]%2==1) fff=-1;
    		val[x]=sum[x]=lf[x]=rg[x]=fff*need;
    		return;
    	}
    	if(L<=mid) change_val(lfc,l,mid);
    	else change_val(rgc,mid+1,r);
    	pushup(x);
    }
    
    int fffff;
    
    void change_qf(int x,int l,int r){
    	if(l==r){
    		sum[x]=lf[x]=rg[x]=val[x]=-w[l]*fffff;
    		return;
    	}
    	if(L<=mid) change_qf(lfc,l,mid);
    	else change_qf(rgc,mid+1,r);
    	pushup(x);
    }
    
    void cz1(){
    	int a,b;
    	read(L);read(a);read(b);
    	if(a%2==1&&b%2==1){fffff=1;
    		change_qf(1,1,n);}
    	else{
    		fffff=-1;
    		change_qf(1,1,n);
    	}
    	xx[L]=a,yy[L]=b;
    }
    
    void cz2(){
    	read(L);read(need);
    	change_val(1,1,n);
    	w[L]=need;
    }
    
    void cz3(){
    	read(L);read(R);
    	printf("%d
    ",query(1,1,n).val);
    }
    
    int main(){
    	freopen("light.in","r",stdin);freopen("light.out","w",stdout);
    	read(n);
    	for(int i=1;i<=n;i++) read(w[i]);
    	for(int i=1;i<=n;i++){
    		read(xx[i]);read(yy[i]);
    	}
    	build(1,1,n);
    	read(T);int op;
    	while(T--){
    		read(op);
    		if(op==1) cz1();
    		if(op==2) cz2();
    		if(op==3) cz3();
    	}
    	return 0;
    }
    

    暗雪

    区间Dp+四边形不等式优化

    这题数据被 (O(n^4)) 氧化钙过去了。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    template <typename Tp>
    void read(Tp &x){
    	x=0;char ch=1;int fh;
    	while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    	if(ch=='-') ch=getchar(),fh=-1;
    	else fh=1;
    	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	x*=fh;
    }
    
    const int maxn=407;
    const int INF=1e18;
    
    int n,kk,a[maxn];
    int dp[maxn][maxn][maxn];
    int opt[maxn][maxn],s[maxn];
    
    void Init(){
    	read(n);read(kk);
    	if(kk<=9&&(1<<kk)<n){
    		puts("-1");exit(0);
    	}
    	for(int i=1;i<=n;i++){
    		read(a[i]);
    	}
    }
    
    void Work(){
    	sort(a+1,a+n+1);
    	for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
    	for(int i=1;i<=n;i++){
    		for(int j=i;j<=n;j++){
    			if(i==j) dp[i][j][0]=0;
    			else dp[i][j][0]=INF;
    		}
    	}
    	for(int k=1;k<=kk;k++){
    		for(int i=1;i<=n;i++) opt[i][i]=i;
    		for(int len=2;len<=n;len++){
    			for(int l=1;l+len-1<=n;l++){
    				int r=l+len-1;
    				dp[l][r][k]=INF;
    				for(int p=opt[l][r-1];p<=opt[l+1][r];p++){
    					if(p+1>r) continue;
    					int val=dp[l][p][k-1]+dp[p+1][r][k-1]+s[r]-s[l-1];
    					if(val<dp[l][r][k]){
    						dp[l][r][k]=val;opt[l][r]=p;
    					}
    				}
    			}
    		}
    	}
    	int div=__gcd(dp[1][n][kk],s[n]);
    	printf("%lld/%lld
    ",dp[1][n][kk]/div,s[n]/div);
    }
    
    signed main(){
    	freopen("snow.in","r",stdin);freopen("snow.out","w",stdout);
    	Init();
    	Work();
    	return 0;
    }
    
  • 相关阅读:
    WPS 模拟手写签名
    Flask 正则匹配路由、异常
    FLASK 加载配置、简单传参调用、指定请求方式、返回json、网页跳转(也可以自己的视图函数)、自定义状态码
    python IDLE 自动提示功能
    PYQT设计无边框窗体
    PYQT窗口居中
    PYQT窗口托盘目录
    PYQT窗口风格
    PYQT窗口可视化编程
    PYQT控件使用
  • 原文地址:https://www.cnblogs.com/liubainian/p/11781041.html
Copyright © 2011-2022 走看看