题面:https://www.cnblogs.com/Juve/articles/11602450.html

u:

用差分优化修改

二维差分:给(x1,y1),(x2,y2)加上s:

$d[x1][y1]+=s,d[x1][y2+1]-=s,d[x2+1][y1]-=s,d[x2+1][y2+1]+=s$

定义2个差分数组d1,d2,分别记录竖列和斜边的差分

$d1[r][c]+=s,d1[r+l-1][c]-=s,d2[r][c+1]-=s,d2[r+l-1][c+l-1]+=s$

统计是求2个前缀和

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int MAXN=1e3+5;
int n,q,a[MAXN][MAXN],b[MAXN][MAXN],c[MAXN][MAXN],d[MAXN][MAXN],ans=0;
int d1[MAXN][MAXN],d2[MAXN][MAXN];
signed main(){
scanf("%lld%lld",&n,&q);
while(q--){
int r,c,l,s;
scanf("%lld%lld%lld%lld",&r,&c,&l,&s);
int N=min(n,r+l-1),M=min(n,c+l-1);
d1[r][c]+=s,d1[N+1][c]-=s;
d2[r][c+1]-=s,d2[N+1][M+2]+=s;
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
a[i][j]=(a[i-1][j]+d1[i][j]);
b[i][j]=(b[i-1][j-1]+d2[i][j]);
c[i][j]=a[i][j]+b[i][j];
d[i][j]=d[i][j-1]+c[i][j];
}
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j)
ans^=d[i][j];
}
printf("%lld\n",ans);
return 0;
}

v:

搜索每一个情况,对于重复的用map记忆化一下

注意判断长度为奇数的情况,map超时可以用hash表

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define re register
using namespace std;
int n,k,sta=0;
char ch[35];
struct hash_map{
int pre[40000000],cnt;
struct node{
int nxt,to,w;
double v;
}e[6000000];
double &operator[](int sta){
int key=1LL*sta%30000019;
for(int i=pre[key];i;i=e[i].nxt)
if(e[i].to==sta) return e[i].v;
e[++cnt].nxt=pre[key];e[cnt].to=sta;;e[cnt].v=-1.0;
pre[key]=cnt;
return e[cnt].v;
}
}mp;
inline double dfs(re int x,re int st){
if(x==n-k) return 0.0;
if(mp[st]!=-1) return mp[st];
mp[st]=0;
re double sum=0.0;
for(re int i=1;i<=x>>1;i++){
re int con1=st>>i-1&1,con2=st>>x-i&1;
re int to1=st>>1&~((1<<i-1)-1)|st&(1<<i-1)-1;
re int to2=st>>1&~((1<<x-i)-1)|st&((1<<x-i)-1);
sum+=2.0*max(dfs(x-1,to1)+con1,dfs(x-1,to2)+con2)/x;
}
if(x&1){
re int i=x+1>>1;
re int to=st>>1&~((1<<i-1)-1)|st&(1<<i-1)-1;
re int con=st>>i-1&1;
sum+=(dfs(x-1,to)+con)/x;
}
return mp[st]=sum;
}
signed main(){
scanf("%d%d",&n,&k);
scanf("%s",ch+1);
for(re int i=1;i<=n;i++)
sta|=(ch[i]=='W')<<n-i;
sta|=1<<n;
printf("%0.7lf\n",dfs(n,sta));
return 0;
}

w:

如果我们选出一条边,就给边两端的点度数加一,那么第一个答案就是度数为奇数的点个数除以2

我们定义dp[i][0/1]表示i节点,没有/有向父亲的反转i边的两个答案

接下来我们考虑更新:
在更新时我们使用两个参量:p和q,作为更新dp的中间步骤,用p代表不以i为端点做链,q代表以i为端点做链,设i的某个子节点为to,于是有:
p=min(p+dp[to][0],q+dp[to][1])
q=min(p+dp[to][1],q+dp[to][0])
其中p初始化为(0,0),q初始化为(INF,INF)
解释一下:这里pair的add就是对应元素相加(手写!非内置!)
而min操作表示先按pair第一关键字比较,再按第二关键字比较
那么这一步就是一个合并的过程:
首先,i不作为链的端点:分两类来合并:如果子节点与i的边翻转了,那么就要累在以i为端点的链里(因为i与父亲的边不翻转,那么i就将是个端点),如果子节点与i的边没有翻转,那么仅针对这棵子树而言,i并没有作为路径的端点,所以更新没有以i为端点链的代价
如果i作为链的端点,同样分两类来合并:如果子节点与i的边翻转了,那么i显然可以成为链的端点,前提是在此之前i并不是链的端点,所以用之前i不是链的端点的代价来更新;反之,如果子节点与i的边没有翻转,那么就此而言i并不是端点,可要求i是链的一个端点,这样就必须用i原先就是链的端点的代价来更新
遍历根节点所有子节点后,更新dp:
如果i与父亲的边没有翻转。即状态dp[i][0]:
首先,i不作为链的端点肯定是一种可能性,直接比较
接着,如果i是链的一个端点,i和父节点的边还没有翻转,那么说明在这个状态下i是真正的奇度点,所以将状态q的first+1后更新
如果i与父亲的边翻转了,同样分两类更新:
首先,i本身作为了链的端点,而由于i本身就是奇度点,所以仅需将q.second+1来更新即可
还有,如果i本身在下面并没有作为链的端点,而i却与父节点的边发生了翻转,所以i就成为了新的奇度点,同时链长还增加了,所以p.first,p.second均增加即可
最后答案即为dp[1][0].first/2,dp[1][0].second

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=5e5+5;
const int inf=0x3f3f3f3f;
int n;
int to[MAXN<<1],nxt[MAXN<<1],pre[MAXN],flag[MAXN<<1],cnt=0;
void add(int u,int v,int val){
++cnt,to[cnt]=v,nxt[cnt]=pre[u],pre[u]=cnt,flag[cnt]=val;
}
struct node{
int tim,len;
friend node operator + (node a,node b){
return (node){a.tim+b.tim,a.len+b.len};
}
friend bool operator < (node a,node b){
return a.tim==b.tim?a.len<b.len:a.tim<b.tim;
}
}dp[MAXN][2];
node min(node a,node b){
return a<b?a:b;
}
void dfs(int x,int fa,int fl){
node p={0,0},q={inf,inf};
for(int i=pre[x];i;i=nxt[i]){
int y=to[i];
if(y==fa) continue;
dfs(y,x,flag[i]);
node a=p,b=q;
p=min(a+dp[y][0],b+dp[y][1]);
q=min(b+dp[y][0],a+dp[y][1]);
}
if(fl==2){
dp[x][0]=min(p,q+(node){1,0});
dp[x][1]=min(p+(node){1,1},q+(node){0,1});
}
if(fl==1){
dp[x][0]=(node){inf,inf};
dp[x][1]=min(p+(node){1,1},q+(node){0,1});
}
if(fl==0){
dp[x][0]=min(p,q+(node){1,0});
dp[x][1]=(node){inf,inf};
}
}
signed main(){
scanf("%d",&n);
for(int i=1,a,b,c,d;i<n;++i){
scanf("%d%d%d%d",&a,&b,&c,&d);
if(d==2){
add(a,b,2),add(b,a,2);
}else{
if(c==d) add(a,b,0),add(b,a,0);
else add(a,b,1),add(b,a,1);
}
}
dfs(1,0,0);
printf("%d %d\n",dp[1][0].tim/2,dp[1][0].len);
return 0;
}

csp-s模拟测试53u,v,w题解的更多相关文章

  1. [CSP模拟测试43、44]题解

    状态极差的两场.感觉现在自己的思维方式很是有问题. (但愿今天考试开始的一刻我不会看到H I J) A 考场上打了最短路+贪心,水了60. 然而正解其实比那30分贪心好想多了. 进行n次乘法后的结果一 ...

  2. [7.18NOIP模拟测试5]砍树 题解(数论分块)

    题面(加密) 又考没学的姿势……不带这么玩的…… 考场上打了个模拟 骗到30分滚粗了 稍加思考(滑稽)可将题面转化为: 求一个最大的$d$,使得 $\sum \limits _{i=1}^n {(\l ...

  3. [20190727NOIP模拟测试9]单(single) 题解(树上dp)

    啊啊啊啊啊啊啊啊考场上差一点就A掉了5555 千里之堤溃于蚁穴……鬼知道最后一步那么显然的柿子我为什么没考虑用上…… 观察数据范围可知,出题人期望我们想出一个$O(n)$的做法 当然也有可能是$O(n ...

  4. [NOIP模拟测试9]题(Problem) 题解 (组合数全家桶+dp)

    达哥送分给我我都不要,感觉自己挺牛批. $type=0:$ 跟visit那题类似,枚举横向移动的步数直接推公式: $ans=\sum C_n^i \times C_i^{\frac{i}{2}} \t ...

  5. [NOIP模拟测试3] 建造游乐园 题解(欧拉图性质)

    Orz 出题人石二队爷 我们可以先求出有n个点的联通欧拉图数量,然后使它删或增一条边得到我们要求的方案 也就是让它乘上$C_n^2$ (n个点里选2个点,要么删边要么连边,选择唯一) 那么接下来就是求 ...

  6. csps-s模拟测试62,63Graph,Permutation,Tree,Game题解

    题面:https://www.cnblogs.com/Juve/articles/11631298.html permutation: 参考:https://www.cnblogs.com/clno1 ...

  7. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  8. noi2019模拟测试赛(四十七)

    noi2019模拟测试赛(四十七) T1与运算(and) 题意: ​ 给你一个序列\(a_i\),定义\(f_i=a_1\&a_2\&\cdots\&a_i\),求这个序列的所 ...

  9. [考试反思]1003csp-s模拟测试58:沉淀

    稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使 ...

随机推荐

  1. python 之单例模式

    单例模式1 单例=>只有一个单例2 静态方法+静态字段3 所有实例中等转的内容相同时 用单例模式class Sqllite: __instance=None def __init__(self) ...

  2. DOM——获取页面元素

    获取页面元素 为什么要获取页面元素 例如:我们想要操作页面上的某部分(显示/隐藏,动画),需要先获取到该部分对应的元素,才进行后续操作 根据id获取元素 var div = document.getE ...

  3. 【转】keepalived+mysql

    https://www.cnblogs.com/gomysql/p/3856484.html MySQL的高可用方案有很多,比如Cluster,MMM,MHA,DRBD等,这些都比较复杂,我前面的文章 ...

  4. java接口的意义,为什么接口可以多继承,而类不可以?

    原文地址:http://www.cnblogs.com/yunxiblog/p/5240690.html java当中继承一个接口,要重写他的方法的话,那为什么还要多此一举的去实现一个接口呢? 直接把 ...

  5. PAT甲级——A1125 Chain the Ropes【25】

    Given some segments of rope, you are supposed to chain them into one rope. Each time you may only fo ...

  6. npm安装vuex及防止页面刷新数据丢失

    npm install vuex 在项目scr目录下新建store文件夹,在store文件夹下新建index.js文件. import Vue from 'vue'; import Vuex from ...

  7. FileCloud 的原理简述&自己搭建文件云

    FileCloud 的原理简述&自己搭建文件云 copyright(c) by zcy 关于如何使用IIS创建asp服务,请读者自行研究 注:不要忘记添加入站规则 代码的存储: 根目录 fil ...

  8. Apache下更改.htaccess文件名称

    有时候我们需要更改.htaccess的名称以解决一些问题 比如:Eclipse下是不显示点开头的文件的 所以我们可以使用  Apache的AccessFileName来更改此配置文件的名称 Acces ...

  9. 开机自动调用.bat文件且浏览器全屏展示

    1,将 .bat文件放入到以下路径中 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup 或 C:\Users\Administr ...

  10. 回首2018 | 分析型数据库AnalyticDB: 不忘初心 砥砺前行

    题记 分析型数据库AnalyticDB(下文简称ADB),是阿里巴巴自主研发.唯一经过超大规模以及核心业务验证的PB级实时数据仓库.截止目前,现有外部支撑客户既包括传统的大中型企业和政府机构,也包括众 ...