写这几个题解我觉得我就像在按照官方题解抄一样

阴阳

题解

将题目中给的阴阳看作黑色和白色

首先我们观察到最后生成图中某种颜色必须是竖着单调递增或竖着单调递减

类似这样

否则不满足这个条件

但合法染色方案必须满足任意两个同颜色格子之间的格子也必须是该颜色。

然后我们分四种情况统计,

1.黑色居于左侧而且分界点单调不降,

2.黑色居于左侧而且分界点单调不升,

3.白色居于左侧而且分界点单调不降,

4.白色居于左侧而且分界点单调不升。

我们发现这样会算重,

dp然后手动容斥,

1,2会算重左面每列全是黑色

类似于

类似的3,4会算重左面全是白色

那么上面全是黑色我们也会算重(2,3)

上面全是白色我们仍然会算重

手动容斥

题解应该都能看懂,实现稍难(不用说了我码力太弱)

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1111
const ll mod=1e9+7;
ll can[A][A][10],f[A][A][2],up[A][A],down[A][A];
//can定义为i行从1--j染成B剩下染成W是否合法
char ch[A][A];
ll n,m,flag1,flag2,ans;
int main(){scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)scanf("%s",ch[i]+1);for(ll i=1;i<=n;i++){ll maxpos=0;for(ll j=1;j<=m;j++){if(ch[i][j]=='W') break;if(ch[i][j]=='B') maxpos=j;}for(ll j=maxpos+1;j<=m;j++)if(ch[i][j]=='B'){maxpos=m+1;    break;}ll now=maxpos;while(ch[i][now]!='W'&&now<=m)can[i][now][1]=1,now++;}for(ll i=1;i<=n;i++){ll maxpos=m+1;for(ll j=m;j>=1;j--){if(ch[i][j]=='W') break;if(ch[i][j]=='B') maxpos=j;}for(ll j=maxpos-1;j>=1;j--)if(ch[i][j]=='B'){maxpos=-1; break;}ll now=maxpos;while(ch[i][now]!='W'&&now>=0)can[i][m-now+1][2]=1,now--;}for(ll i=0;i<=m;i++)up[0][i]=1,down[0][i]=1;for(ll i=1;i<=n;i++){for(ll j=0;j<=m;j++){if(!can[i][j][1]) continue;f[i][j][0]=up[i-1][j];f[i][j][1]=down[i-1][j];
//            printf("up[%lld][%lld]=%lld down=%lld\n",i-1,j,up[i-1][j],down[i-1][j]);
        }for(ll j=0;j<=m;j++)up[i][j]=(up[i][j-1]+f[i][j][0])%mod/*,printf("f=%lld up=%lld\n",f[i][j][0],up[i][j])*/;for(ll j=m;j>=0;j--)down[i][j]=(down[i][j+1]+f[i][j][1])%mod;
//        printf("up=%lld down=%lld\n",up[n][m],down[n][0]);
    }
/*    for(ll i=1;i<=n;i++,puts("")){for(ll j=1;j<=m;j++){printf("%lld ",can[i][j][1]);}}
*/    memset(f,0,sizeof(f));ans=(ans+up[n][m]+down[n][0]+mod)%mod;
//    printf("ans=%lld\n",ans);for(ll i=1;i<=n;i++){for(ll j=0;j<=m;j++){if(!can[i][j][2]) continue;f[i][j][0]=up[i-1][j];f[i][j][1]=down[i-1][j];}for(ll j=0;j<=m;j++)up[i][j]=(up[i][j-1]+f[i][j][0])%mod;for(ll j=m;j>=0;j--)down[i][j]=(down[i][j+1]+f[i][j][1])%mod;}
//    printf("up=%lld down=%lld\n",up[n][m],down[n][0]);ans=(ans+up[n][m]+down[n][0]+mod)%mod;
//    printf("ans=%lld\n",ans);memset(f,0,sizeof(f));//减去左右重复for(ll i=1;i<m;i++){ll flag=0;for(ll j=1;j<=n;j++)if(!can[j][i][1]){flag=1;break;}if(!flag) ans--;}for(ll i=1;i<m;i++){ll flag=0;for(ll j=1;j<=n;j++)if(!can[j][i][2]){flag=1;break;}if(!flag) ans--;}//减去上下//若上面为B下面只能为Wfor(ll i=1;i<n;i++){ll flag=0;for(ll j=1;j<=i;j++)if(!can[j][m][1]){flag=1;break;}for(ll j=i+1;j<=n;j++)if(!can[j][0][1]){flag=1;break;}if(flag)continue;ans--;}for(ll i=n;i>=2;i--){ll flag=0;for(ll j=1;j<=i-1;j++)if(!can[j][0][1]){flag=1;break;}for(ll j=i;j<=n;j++)if(!can[j][m][1]){flag=1;break;}if(flag)continue;ans--;}for(ll i=1;i<=n;i++){if(!can[i][0][1])    flag1=1;if(!can[i][m][1])    flag2=1;}if(!flag1) ans-=3;if(!flag2) ans-=3;printf("%lld\n",(ans+mod)%mod);
}

View Code

题解

我们发现一条性质我们子树内两个点要变成黑色我们同时经过树外的边不会使次数变优(除了直接与lca相连的边)

然后根据这条性质,我们发现我们一定存在一种最优方案使任意两条染色路径互不相交

然后我们进行贪心

首先题目中给的无要求的边我们进行缩边

我们统计到当前子树都已经全部染成黑色了,那么我们只用考虑与它相连就行

拿下面这个图举例(假设全部为白边)

你考虑3时你6的子树都处理完了,然后你遇到两个白色边(3,6)(3,7)你贪心直接染色就行,那么如果最后剩下一个没有染色怎么办,显然我们不用管,我们发现与3相连的边(1,3)这条边是必定被染色的,2本来要和3进行染色让(1,2)(1,3)进行染色,我们现在把这个边拉过来变成(2,8)进行染色就行了

那么依据上文说的,我们只需要让与3相连白边个数(除了父亲与它相连边)/2就行了

推广到所有点统计白边个数/2即可

然后这样做对于根来说会出错,特判一下就AC了(对于根来说没有办法再让自己父亲拉边过来)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define R register
#define ll long long
inline ll read()//-------
{ll aa=0;char cc=getchar();while(cc<'0'||cc>'9') cc=getchar();while(cc<='9'&&cc>='0'){aa=(aa<<3)+(aa<<1)+(cc^48);cc=getchar();}return aa;
}
const int N=1000005;
struct tree{int v,last;
}tr[N<<1];
int tot,first[N];
inline void add(int x,int y)
{tr[++tot]=(tree){y,first[x]};first[x]=tot;return;
}
int n,ans,mp[N],vi[N];
int dfs(int x,int fa)
{int sum=0;vi[x]=1;for(R int i=first[x],v;i;i=tr[i].last){v=tr[i].v;if(v==fa)continue;dfs(v,x);sum^=1;if(!sum)++ans;}return sum;
}
int main()
{//freopen("tight.in","r",stdin);//freopen("tight.out","w",stdout);n=read();mp[1]=++mp[0];for(R int i=2,x,y,z;i<=n;++i){x=read();y=read();z=read();if(!z){if(mp[i])mp[x]=mp[i];else if(mp[x])mp[i]=mp[x];else mp[i]=mp[x]=++mp[0];continue;}if(!mp[i])mp[i]=++mp[0];if(!mp[x])mp[x]=++mp[0];if(y)continue;add(mp[i],mp[x]);add(mp[x],mp[i]);}for(R int i=1;i<=mp[0];++i)if(!vi[i])if(dfs(i,i))++ans;printf("%d",ans);return 0;
}

View Code

转载于:https://www.cnblogs.com/znsbc-13/p/11424317.html

NOIP模拟测试28「阴阳·虎·山洞」相关推荐

  1. NOIP模拟测试19「count·dinner·chess」

    反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...

  2. NOIP模拟测试30「return·one·magic」

    magic 题解 首先原式指数肯定会爆$long$ $long$ 首先根据欧拉定理我们可以将原式换成$N^{\sum\limits_{i=1}^{i<=N} [gcd(i,N)==1] C_{G ...

  3. NOIP模拟测试21「折纸·不等式」

    折纸 题解 考试时无限接近正解,然而最终也只是接近而已了 考虑模拟会爆炸,拿手折纸条试一试,很简单 考你动手能力 代码 #include<bits/stdc++.h> using name ...

  4. NOIP模拟测试38「金·斯诺·赤」

    金 辗转相减见祖宗 高精 #include<bits/stdc++.h> using namespace std; #define A 2000 #define P 1 #define N ...

  5. NOIP模拟测试20「周·任·飞」

    liu_runda出的题再次$\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%\%$ 任 题解 题目中为什么反复强调简单路径,没有环 没有环的图中点数-边数=联通块数 前缀和维护边 ...

  6. NOIP模拟测试23「mine·water·gcd」

    mine 题解 一道比较水的dp 考试因为初始化挂掉了只有$80$分 代码有注释 #include<bits/stdc++.h> using namespace std; //无脑dp # ...

  7. NOIP模拟测试17「入阵曲·将军令·星空」

    入阵曲 题解 应用了一种美妙移项思想, 我们先考虑在一维上的做法 维护前缀和$(sum[r]-sum[l-1])\%k==0$可以转化为 $sum[r]\% k==sum[l-1]\%k$开个桶维护一 ...

  8. NOIP模拟测试16「Drink·blue·weed」

    话说这次考试 Drink 非常棒的一道卡常练习题,适合练习卡常 真的很棒 前置卡常知识 1.char要比int快 char是最快的 输出putchar,输入getchar 在这个题快了7000豪 2. ...

  9. NOIP模拟测试11「string·matrix·big」

    打的big出了点小问题,maxx初值我设的0然后少了10分 第二题暴力打炸 第一题剪了一些没用的枝依然40分 总分70 这是一次失败的考试 string 想到和序列那个题很像,但我没做序列,考场回忆学 ...

最新文章

  1. 想避免重复请求/并发请求?这样处理才足够优雅
  2. ios 标签 html,ios HTML的标签的过滤
  3. c# 对象json互相转换_C#匿名对象(转JSON)互转、动态添加属性
  4. python统计字符串中每个单词出现的次数_python中每个单词出现的次数是一组字符串?...
  5. SpringMVC经典系列-14自己定义SpringMVC的拦截器---【LinusZhu】
  6. html只能输入两位小数,JQuery控制input只能输入数字和两位小数(有关金额)代码...
  7. Delphi初浅入门笔记之六:高级数据类型
  8. centos下yum安装lamp
  9. Nifi从入门到精通(一)之 数据存储
  10. 关于onclick=open([Object obj],[Object obj])的问题
  11. OWASP A6 Vulnerable and Outdated Components (自带缺陷和过时的组件)
  12. ARM STMFD, STMFA, STMED, STMEA, LDMFD, LDMFA, LDMED, LDMEA
  13. Docker常用命令大全(万字详解)
  14. 什么是网络号,主机号,主机地址,网络地址,主机地址,子网号,子网地址
  15. 基于 keepalived 实现两台机器服务(主备)故障自动切换
  16. 矩阵的秩和图像的秩的一些了解
  17. 健身训练计时器(2-1)-GUI
  18. 解决NPM下载速度贼慢的方法
  19. BM817模块内置协议栈的开发笔记
  20. RSA基本原理及常见攻击方法

热门文章

  1. python编码程序_python 编码
  2. Linux 命令之 deluser -- 删除用户
  3. android图标随着进度条动画,Android开发之ProgressBar字体随着进度条的加载而滚动...
  4. python操纵excel的方法_python操作Excel的几种方式
  5. @cacheable 是否缓存成功_缓存策略:如何使用缓存来减少磁盘IO?
  6. java关闭websocket_关闭代码1006关闭websocket的原因
  7. c语言中Gretchen函数的功能,听过很多的歌的音乐达人给我推荐一下
  8. 【WebRTC---进阶篇】(六)SELECT网络模型
  9. centos php支持yaf,CentOS环境下给PHP7.0安装yaf扩展
  10. java 多线程 聊天_Java做一个多线程类似于QQ的聊天程序。