zoukankan      html  css  js  c++  java
  • UOJ#346. 【清华集训2017】某位歌姬的故事 动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ346.html

    题解

    首先按照 $m_i$ 的大小排个序。

    如果某一个区间和一个 m 值比他小的区间有交,那么显然可以将这个区间控制的区域删除掉重合的那一段。

    如果一个区间被删没了,那么显然答案为 0 。

    在这个处理之后,一个区间可能会变得不连续。那么我们就将它前后相连,变成连续的。

    接下来问题变成了对每一种权值的区间算答案。

    这个东西离散化之后大力DP即可。

    注意特判权值为 1 的区间。

    写起来好像有点麻烦。

    时间复杂度 $O(Tn^2)$ 。

    代码

    #pragma GCC optimize("Ofast","inline")
    #include <bits/stdc++.h>
    #define clr(x) memset(x,0,sizeof (x))
    #define For(i,a,b) for (int i=a;i<=b;i++)
    #define Fod(i,b,a) for (int i=b;i>=a;i--)
    #define pb(x) push_back(x)
    #define mp(x,y) make_pair(x,y)
    #define fi first
    #define se second
    #define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
    #define outval(x) printf(#x" = %d
    ",x)
    #define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
    #define outtag(x) puts("----------"#x"----------")
    #define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);
    						For(_v2,L,R)printf("%d ",a[_v2]);puts("");
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector <int> vi;
    LL read(){
    	LL x=0,f=0;
    	char ch=getchar();
    	while (!isdigit(ch))
    		f|=ch=='-',ch=getchar();
    	while (isdigit(ch))
    		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	return f?-x:x;
    }
    const int N=1005,mod=998244353;
    int Pow(int x,int y){
    	int ans=1;
    	for (;y;y>>=1,x=(LL)x*x%mod)
    		if (y&1)
    			ans=(LL)ans*x%mod;
    	return ans;
    }
    void Add(int &x,int y){
    	if ((x+=y)>=mod)
    		x-=mod;
    }
    void Del(int &x,int y){
    	if ((x-=y)<0)
    		x+=mod;
    }
    int n,q,ub;
    int Ha[N],hs=0;
    int sum[N],vis[N];
    struct S{
    	int L,R,v;
    }a[N],b[N][N];
    int c[N];
    bool cmp(S a,S b){
    	if (a.v!=b.v)
    		return a.v<b.v;
    	if (a.L!=b.L)
    		return a.L<b.L;
    	return a.R<b.R;
    }
    int calc(int n,S *A){
    	static S a[N];
    	static int kill[N],len[N],pw0[N],pw1[N],iv0[N],iv1[N];
    	static int Ha[N],rp[N],dp[N];
    	int m=0,hs=0;
    	For(i,1,n-1)
    		assert(A[i].L<=A[i+1].L);
    	clr(kill);
    	For(i,1,n)
    		For(j,i+1,n)
    			if (A[i].L<=A[j].L&&A[j].R<=A[i].R)
    				kill[i]=1;
    	For(i,1,n)
    	 	Ha[++hs]=A[i].L,Ha[++hs]=A[i].R+1;
    	sort(Ha+1,Ha+hs+1);
    	hs=unique(Ha+1,Ha+hs+1)-Ha-1;
    	clr(len);
    	For(i,1,n){
    		int L=lower_bound(Ha+1,Ha+hs+1,A[i].L)-Ha;
    		int R=lower_bound(Ha+1,Ha+hs+1,A[i].R+1)-Ha;
    		For(j,L+1,R)
    			len[j]=Ha[j]-Ha[j-1];
    	}
    	For(i,1,n)
    		if (!kill[i])
    			a[++m]=A[i];
    	int v=a[1].v;
    	if (v==1)
    		return 1;
    	n=m;
    	pw0[1]=iv0[1]=1;
    	For(i,2,hs){
    		int tmp=len[i];
    		pw0[i]=(LL)pw0[i-1]*Pow(v-1,tmp)%mod;
    		pw1[i]=(Pow(v,tmp)-Pow(v-1,tmp)+mod)%mod;
    		iv0[i]=Pow(pw0[i],mod-2);
    	}
    	For(i,1,hs)
    		rp[i]=hs+1;
    	For(i,1,n){
    		a[i].L=lower_bound(Ha+1,Ha+hs+1,a[i].L)-Ha+1;
    		a[i].R=lower_bound(Ha+1,Ha+hs+1,a[i].R+1)-Ha;
    		For(j,1,a[i].L-1)
    			rp[j]=min(rp[j],a[i].R);
    	}
    	int ans=0;
    	clr(dp),dp[1]=1;
    	For(i,1,hs){
    		For(j,i+1,rp[i])
    			Add(dp[j],(LL)dp[i]*pw0[j-1]%mod*iv0[i]%mod*pw1[j]%mod);
    		if (rp[i]==hs+1)
    			Add(ans,(LL)dp[i]*pw0[hs]%mod*iv0[i]%mod);
    	}
    	return ans;
    }
    void Solve(){
    	n=read(),q=read(),ub=read();
    	clr(Ha),hs=0;
    	For(i,1,q){
    		a[i].L=read(),a[i].R=read(),a[i].v=read();
    		Ha[++hs]=a[i].L,Ha[++hs]=a[i].R+1;
    	}
    	Ha[++hs]=1,Ha[++hs]=n+1;
    	sort(Ha+1,Ha+hs+1);
    	hs=unique(Ha+1,Ha+hs+1)-Ha-1;
    	Ha[0]=1;
    	clr(vis);
    	sort(a+1,a+q+1,cmp);
    	int cnt=0;
    	for (int i=1,j;i<=q;i=j+1){
    		j=i,c[++cnt]=0;
    		while (j<q&&a[j+1].v==a[i].v)
    			j++;
    		For(k,1,hs)
    			sum[k]=sum[k-1]+(vis[k]?0:Ha[k]-Ha[k-1]);
    		For(k,i,j){
    			int L=a[k].L=lower_bound(Ha+1,Ha+hs+1,a[k].L)-Ha;
    			int R=a[k].R=lower_bound(Ha+1,Ha+hs+1,a[k].R+1)-Ha;
    			if (L==R){
    				puts("0");
    				return;
    			}
    			c[cnt]++;
    			b[cnt][c[cnt]].L=sum[L]+1;
    			b[cnt][c[cnt]].R=sum[R];
    			b[cnt][c[cnt]].v=a[k].v;
    		}
    		For(k,i,j)
    			For(t,a[k].L+1,a[k].R)
    				vis[t]=1;
    	}
    	int ans=1;
    	For(i,2,hs)
    		if (!vis[i])
    			ans=(LL)ans*Pow(ub,Ha[i]-Ha[i-1])%mod;
    	For(i,1,cnt)
    		ans=(LL)ans*calc(c[i],b[i])%mod;
    	cout<<ans<<endl;
    }
    int main(){
    	int T=read();
    	while (T--)
    		Solve();
    	return 0;
    }
    

      

  • 相关阅读:
    CPT104-labs
    Java-数据结构-ArrayList
    INT104-lab13[Parzen Window Method][此方法无数据集划分]
    INT104-lab12 [KNN Algorithm][lambda表达式]
    INT104-lab11 [聚类] [iris数据集] [K-means Algorithm]
    Nginx配置https兼容http
    JS获取整个网页html代码
    nginx重启生效conf文件的修改
    WampServer
    在win10系统中,开启hyper-v要满足下列条件
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/UOJ346.html
Copyright © 2011-2022 走看看