好神的题啊!

看了这题只会第一个subtask,又参考了HN-CJ鸽王zsy的题解,实在太菜了。

暴力转移是O(nc2),很显然没有分。考虑子任务1,2,只需要转移包含已染色格子的列,然后状态数只有O(nc),对于关键两列(即有染色的列)间,只有5种状态。而这个可以初始化转移,转移讨论有点复杂,而且我不会用数学公式,就不打出吧。转移后即可直接DP。然后对于子任务3,4,把它们分割即可,把两边方案乘起来就行了,于是可以做到O(nc),得到96分的好成绩。然后听Claris所述,DP所有转移操作即为T1的操作,于是可以做到O(n+c)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+,mod=1e9+;
int n,m,tot,ans=,a[N],b[N],c[N],p[N],g[N][];
int qpow(int a,int b)
{
int ret=;
while(b)
{
if(b&)ret=1ll*ret*a%mod;
a=1ll*a*a%mod,b>>=;
}
return ret;
}
struct array{
int mul,add,inv,sum,top,s[N<<],f[N];
array(){mul=inv=;}
void modify(int x,int v)
{
sum=(sum+1ll*(mod-f[x])*mul+mod-add)%mod;
f[x]=1ll*(v-add+mod)*inv%mod,s[++top]=x,sum=(sum+v)%mod;
}
void plus(int v){sum=(sum+1ll*m*v)%mod,add=(add+v)%mod;}
void cover(int v)
{
while(top)f[s[top--]]=;
mul=inv=,add=v,sum=1ll*m*v%mod;
}
void mult(int v)
{
if(v)
sum=1ll*sum*v%mod,mul=1ll*mul*v%mod,add=1ll*add*v%mod,inv=1ll*inv*qpow(v,mod-)%mod;
else cover();
}
int query(int x)
{
if(x)return(1ll*f[x]*mul+add)%mod;
return sum;
}
}F;
void trans(int x,int y,int z,int w)
{
if(x!=y)
{
int fy=F.query(y),sum=(F.query()-fy+mod)%mod;
F.mult((g[z][^w]-g[z][]+mod)%mod);
F.plus((1ll*sum*g[z][]+1ll*fy*g[z][^w])%mod);
F.modify(x,(1ll*sum*g[z][^w]+1ll*fy*g[z][^w])%mod);
F.modify(y,);
}
else{
int sum=F.query();
F.mult((g[z][^w]-g[z][^w]+mod)%mod);
F.plus(1ll*sum*g[z][^w]%mod);
F.modify(x,);
}
}
void build(int x,int y,int z,int w)
{
if(w==x)F.cover(g[z][]),F.modify(x,),F.modify(y,g[z][]);
else if(w==y)F.cover(g[z][]),F.modify(x,g[z][]),F.modify(y,);
else F.cover(g[z][]),F.modify(x,g[z][]),F.modify(y,g[z][]),F.modify(w,);
}
void solve(int x,int y,int z,int w)
{
int ret=;
if(w==x)
{
int fy=F.query(y),sum=(F.query()-fy+mod)%mod;
ret=(1ll*sum*g[z][]+1ll*fy*g[z][])%mod;
}
else if(w==y)
{
int fx=F.query(x),sum=(F.query()-fx+mod)%mod;
ret=(1ll*sum*g[z][]+1ll*fx*g[z][])%mod;
}
else{
int fx=F.query(x),fy=F.query(y),sum=(1ll*F.query()-fx-fy+*mod)%mod;
ret=(1ll*sum*g[z][]+1ll*fx*g[z][]+1ll*fy*g[z][])%mod;
}
ans=1ll*ans*ret%mod;
}
int cal(int x,int y,int z,int u,int v)
{
if(x==u)return y==v?g[z][]:g[z][];
if(x==v)return y==u?g[z][]:g[z][];
if(y==u)return g[z][];
if(y==v)return g[z][];
return g[z][];
}
int main()
{
scanf("%d%d",&n,&m);
int mp[][]={{,,,m-,1ll*(m-)*(m-)%mod},
{,,m-,,1ll*(m-)*(m-)%mod},{,,m-,*m-,2ll*(m-)*(m-)%mod},
{,,*m-,m-,2ll*(m-)*(m-)%mod},{,,m-,m-,1ll*(m-)*(m-)%mod+}};
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]&&a[i]==a[i-]){puts("");return ;}
}
for(int i=;i<=n;i++)
{
scanf("%d",&b[i]);
if(b[i]&&(a[i]==b[i]||b[i]==b[i-])){puts("");return ;}
}
g[][]=;
for(int i=;i<=n;i++)
for(int j=;j<;j++)
for(int k=;k<;k++)
g[i][k]=(g[i][k]+1ll*g[i-][j]*mp[j][k])%mod;
int v1=qpow(m-,mod-),v2=qpow(1ll*(m-)*(m-)%mod,mod-);
for(int i=;i<=n;i++)
g[i][]=1ll*g[i][]*v1%mod,g[i][]=1ll*g[i][]*v1%mod,g[i][]=1ll*g[i][]*v2%mod;
for(int i=;i<=n;i++)
if(a[i]||b[i])
{
p[++tot]=i;
if(b[i]&&!a[i])swap(a[i],b[i]),c[i]=;
else if(b[i])c[i]=;
}
int pw=qpow(1ll*(m-)*(m-)%mod+,p[]-);
if(c[p[]]<)F.cover(pw),F.modify(a[p[]],);else ans=pw;
for(int i=;i<=tot;i++)
if(c[p[i-]]==)
if(c[p[i]]==)ans=1ll*ans*cal(a[p[i-]],b[p[i-]],p[i]-p[i-],a[p[i]],b[p[i]])%mod;
else{
if(c[p[i]])swap(a[p[i-]],b[p[i-]]);
build(a[p[i-]],b[p[i-]],p[i]-p[i-],a[p[i]]);
if(c[p[i]])swap(a[p[i-]],b[p[i-]]);
}
else if(c[p[i]]==)
{
if(c[p[i-]])swap(a[p[i]],b[p[i]]);
solve(a[p[i]],b[p[i]],p[i]-p[i-],a[p[i-]]);
if(c[p[i-]])swap(a[p[i]],b[p[i]]);
}
else trans(a[p[i-]],a[p[i]],p[i]-p[i-],c[p[i]]^c[p[i-]]);
if(c[p[tot]]<)ans=1ll*ans*F.query()%mod;
ans=1ll*ans*qpow(1ll*(m-)*(m-)%mod+,n-p[tot])%mod;
printf("%d",ans);
}

[SDOI2019]染色(DP)的更多相关文章

  1. Educational Codeforces Round 62 (Rated for Div. 2)E(染色DP,构造,思维,组合数学)

    #include<bits/stdc++.h>using namespace std;const long long mod=998244353;long long f[200007][2 ...

  2. 【POJ 1112】Team Them Up!(二分图染色+DP)

    Description Your task is to divide a number of persons into two teams, in such a way, that: everyone ...

  3. poj-1112 (二分图染色+dp分组)

    #include <iostream> #include <algorithm> #include <cstring> using namespace std; ; ...

  4. 【xsy1172】 染色 dp

    题目大意:现有$n$条排成一行的木板,每个木板有一个目标颜色.你每次能将一个区间内的木板分别染成它们的目标颜色,而这次染色的代价为这个区间内不同目标颜色的木板的数量的平方.问将全部木板染成目标颜色的最 ...

  5. BZOJ:2958 序列染色 DP

    bzoj2958 序列染色 题目传送门 Description 给出一个长度为N由B.W.X三种字符组成的字符串S,你需要把每一个X染成B或W中的一个. 对于给出的K,问有多少种染色方式使得存在整数a ...

  6. 染色dp(确定一行就可行)

    题:https://codeforces.com/contest/1027/problem/E 题意:给定n*n的方格,可以染黑白,要求相邻俩行”完全“不同或完全相同,对于列也是一样.然后限制不能拥有 ...

  7. 5.29 省选模拟赛 树的染色 dp 最优性优化

    LINK:树的染色 考场上以为这道题要爆蛋了 没想到 推出正解来了. 反正是先写了爆搜的 爆搜最近越写越熟练了 容易想到dp 容易设出状态 f[i][j]表示以i为根的子树内白色的值为j此时黑色的值怎 ...

  8. bzoj2958: 序列染色(DP)

    2958: 序列染色 题目:传送门 题解: 大难题啊(还是我太菜了) %一发大佬QTT 代码: #include<cstdio> #include<cstring> #incl ...

  9. Atcoder Grand Contest 031B(DP,思维)

    #include<bits/stdc++.h>using namespace std;int a[200007];int b[200007];long long dp[200007];lo ...

随机推荐

  1. ansible下载文件的多种方式

    对于ansible来说,下载文件是一个很重要的课题,这是build或者deploy的第一步,通常来讲由于不同项目的差异,可能我们的代码包或者资源文件保存在于http,github,nexus,ftp, ...

  2. vector删除指定元素

    #pragma once #include "stdafx.h" #include<windows.h> #include <vector> #includ ...

  3. 牛客——Rabbit的字符串

    题目: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 题目描述 Rabbit得到了一个字符串,她的好朋 ...

  4. 69.ORM查询条件:isnull和regex的使用

    首先查看数据库中的article表的数据: 定义模型的文件models.py中的示例代码如下: from django.db import models class Category(models.M ...

  5. Windows安装使用SonarQube7.4 对java项目进行代码质量扫描

    我这里使用7.4因为使用JDK是1.8 其它版本看下依赖版本就好 1.下载7.4版本安装包 https://binaries.sonarsource.com/CommercialDistributio ...

  6. CF round #622 (div2)

    CF Round 622 div2 A.简单模拟 B.数学 题意: 某人A参加一个比赛,共n人参加,有两轮,给定这两轮的名次x,y,总排名记为两轮排名和x+y,此值越小名次越前,并且对于与A同分者而言 ...

  7. 并发与高并发(七)-线程安全性-原子性-atomic

    一.线程安全性定义 定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程 ...

  8. Linux(CENTOS7) RabbitMq安装

    RabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...

  9. 拷贝构造函数[c++]

    拷贝构造函数何时会被调用? 1. 对象以值传递的方式传入函数参数 2.对象以值传递的方式从函数返回 3.对象需要通过另外一个对象进行初始化 下面我们来看代码: //#include <iostr ...

  10. php 设计模式之策略者模式

    <?php header('Content-Type:text/html;charset=utf-8'); /** * 策略模式演示代码 * * 为了更好地突出“策略”,我们这里以出行为例演示, ...