总结:

数据范围问题(int / long long )

题意问题

try a try. 1e4dinic冲冲冲

不要看到过的人暂时比较少就不敢写,@byf

比赛不要划水聊天

 


 

题解:

A Blank

 题意:题目意思是让你去找一个有n个数的数组,这个数组里面的数只有{0,1,2,3}。然后给你m个条件,每个条件有一组l,r,x,表示在数组l,r区间的有x个不同的数。

问你这样的数组有多少个。

思路:比赛时没想到,,,看题解写的。定义 dp[i][j][k][t] 代表填完前 t 个位置后,{0, 1, 2, 3} 这 4 个数字最后一次出现的位置,排序后为 i, j, k, t(i < j < k < t) 的方案数目,则按照第 t + 1 位的数字的四种选择,可以得到四种转移。对于限制可以按照限制区间的右端点分类,求出 dp[i][j][k][t] 后,找到所有以 t 为区间右端点的限制条件,如果当前状态不满足所有限制条件则不合法,不再向后转移。

 

参考代码:

#include<bits/stdc++.h>
using namespace std;
#define pii pair<in,int>
#define mkp make_pair
#define fi first
#define se second
#define pb push_back
#define mod 998244353
typedef long long ll;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
void add(int &a,int b){a+=b;if(a>=mod)a-=mod;} 
const int maxn=110;
int T,n,m,ans;
int f[maxn][maxn][maxn][2];
vector<pair<int,int> > d[maxn];

int main()
{
    T=read();
    while(T--)
    {
        int l,r,x;
        ans=0;
        n=read();m=read();
        for(int i=1;i<=n;i++)
        {
            d[i].clear();
              d[i].pb(mkp(i,1));
        }   
        for(int i=1;i<=m;i++)
        {
               l=read(),r=read(),x=read();
               d[r].pb(mkp(l,x));
        }
        memset(f,0,sizeof(f));
        f[0][0][0][0]=1;
        for(int cur=1;cur<=n;++cur)
        {
            int o=cur&1;
            for(int i=0;i<=cur;++i)
                for(int j=i;j<=cur;++j)
                    for(int k=j;k<=cur;++k)
                        f[i][j][k][o]=0;
                        
            for(int i=0;i<=cur;++i)
                for(int j=i;j<=cur;++j)
                    for(int k=j;k<=cur;++k)
                    {
                        add(f[j][k][cur-1][o],f[i][j][k][o^1]);
                        add(f[i][k][cur-1][o],f[i][j][k][o^1]);    
                        add(f[i][j][cur-1][o],f[i][j][k][o^1]);
                        add(f[i][j][k][o],f[i][j][k][o^1]);
                    }
                    
            for(int i=0;i<=cur;++i)
                for(int j=i;j<=cur;++j)
                    for(int k=j;k<=cur;++k)
                    {    
                        for(auto pi:d[cur])
                           {
                               int l=pi.first,r=cur,x=pi.second;
                               if((i>=l)+(j>=l)+(k>=l)+(cur>=l)!=x)
                                 f[i][j][k][o]=0;
                           }
                    }
        }
        
        for(int i=0;i<=n;++i)
                for(int j=i;j<=n;++j)
                    for(int k=j;k<=n;++k)
                        add(ans,f[i][j][k][n&1]);    
        
        printf("%d\n",ans);
    }
    
    
    return 0;    
}
View Code

相关文章: