Codeforces round 1086
Div1 528
- 我菜哭了.jpg
- 这个C的出题人能不能停止出题啊QaQ
A
- 这不是裸的斯坦纳树嘛!
然后我就写上了.jpg
然后我没调出来...
然后我发现...这不是傻逼题吗...
直接按照$x$排序,然后做一条恰好够高的线
分别连向两边...
完事了.jpg
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <queue>
using namespace std;
struct node{int x,y;}s[10];
bool cmp(const node &a,const node &b){return a.x==b.x?a.y<b.y:a.x<b.x;}
int main()
{
for(int i=1;i<=3;i++)scanf("%d%d",&s[i].x,&s[i].y);
sort(s+1,s+4,cmp);
int l=min(s[1].y,min(s[2].y,s[3].y)),r=max(s[1].y,max(s[2].y,s[3].y));
printf("%d\n",(s[3].x-s[1].x)+r-l+1);
for(int i=l;i<=r;i++)printf("%d %d\n",s[2].x,i);
for(int i=s[1].x;i<s[2].x;i++)printf("%d %d\n",i,s[1].y);
for(int i=s[2].x+1;i<=s[3].x;i++)printf("%d %d\n",i,s[3].y);
}
B
一个非常显然的贪心,就是把权值全都放在叶子上...
然后就完事了.jpg
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<stack>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 100005
int d[N],n,x,y;
int ans;
double m;
int main()
{
scanf("%d%lf",&n,&m);
for(int i=1;i<n;i++)scanf("%d%d",&x,&y),d[x]++,d[y]++;
if(n==2)return printf("%.6f\n",m),0;
for(int i=1;i<=n;i++)ans+=(d[i]==1);
return printf("%.7f\n",m/ans*(double)2),0;
}
C
没有题解,题目非常傻逼
直接分类讨论即可.jpg
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <queue>
using namespace std;
#define N 1000005
char a[N],b[N],s[N];
int k,T,tmp[27],vis[27],p,n,tt[27],vv[27];
bool check(int x,int cas)
{
memcpy(tt,tmp,sizeof(tt));
memcpy(vv,vis,sizeof(vv));
if(cas==1)
{
for(int i=x;i<=n;i++)
{
if(tt[s[i]-'a']!=-1)
{
if(tt[s[i]-'a']>a[i])return 1;
if(tt[s[i]-'a']<a[i])return 0;
continue;
}
for(int j=a[i]+1;j<=k+'a'-1;j++)if(!vv[j-'a'])return 1;
if(!vv[a[i]-'a'])vv[a[i]-'a']=1,tt[s[i]-'a']=a[i];
else return 0;
}
return 1;
}else
{
for(int i=x;i<=n;i++)
{
if(tt[s[i]-'a']!=-1)
{
if(tt[s[i]-'a']>b[i])return 0;
if(tt[s[i]-'a']<b[i])return 1;
continue;
}
for(int j='a';j<b[i];j++)if(!vv[j-'a'])return 1;
if(!vv[b[i]-'a'])vv[b[i]-'a']=1,tt[s[i]-'a']=b[i];
else return 0;
}
return 1;
}
}
void solve()
{
scanf("%d%s%s%s",&k,s+1,a+1,b+1);
n=strlen(s+1);
memset(tmp,-1,sizeof(tmp));p=n+1;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
if(a[i]==b[i])
{
if(tmp[s[i]-'a']==a[i])continue;
if(tmp[s[i]-'a']==-1&&!vis[a[i]-'a'])tmp[s[i]-'a']=a[i],vis[a[i]-'a']=1;
else{puts("NO");return ;}
}else{p=i;break;}
int flag=0;
for(int i=p;i<=n;i++)
{
if(!flag&&a[i]>b[i]){puts("NO");return ;}
if(tmp[s[i]-'a']!=-1)
{
if((((flag&2)==0)&&tmp[s[i]-'a']<a[i])||(((flag&4)==0)&&tmp[s[i]-'a']>b[i])){puts("NO");return ;}
if((flag&2)==0&&tmp[s[i]-'a']>a[i])flag|=2;
if((flag&4)==0&&tmp[s[i]-'a']<b[i])flag|=4;
}else if((flag&6)==0)
{
bool used=0;
for(int j=a[i]+1;j<b[i];j++)
if(!vis[j-'a'])
{
tmp[s[i]-'a']=j;
vis[j-'a']=1;
flag|=6;
used=1;
break;
}
if(!used)
{
if(!used&&!vis[b[i]-'a'])
{
vis[b[i]-'a']=1,tmp[s[i]-'a']=b[i];
if(!check(i+1,2))vis[b[i]-'a']=0,tmp[s[i]-'a']=-1;
else flag|=2,used=1;
}
if(!used&&!vis[a[i]-'a'])
{
vis[a[i]-'a']=1,tmp[s[i]-'a']=a[i];
if(check(i+1,1))flag|=4,used=1;
}
if(!used){puts("NO");return ;}
}
}else if((flag&2)==0)
{
bool used=0;
for(int j=a[i]+1;j<=k+'a'-1;j++)
if(!vis[j-'a'])
{
tmp[s[i]-'a']=j;
vis[j-'a']=1;
flag|=2;
used=1;
break;
}
if(!used)
{
if(!vis[a[i]-'a'])vis[a[i]-'a']=1,tmp[s[i]-'a']=a[i];
else{puts("NO");return ;}
}
}else if((flag&4)==0)
{
bool used=0;
for(int j='a';j<b[i];j++)
if(!vis[j-'a'])
{
tmp[s[i]-'a']=j;
vis[j-'a']=1;
flag|=4;
used=1;
break;
}
if(!used)
{
if(!vis[b[i]-'a'])vis[b[i]-'a']=1,tmp[s[i]-'a']=b[i];
else{puts("NO");return ;}
}
}
flag|=1;
if(flag==7)break;
}
puts("YES");
int now=0;
while(vis[now])now++;
for(int i=0;i<k;i++)
if(tmp[i]==-1){tmp[i]='a'+now;vis[now]=1;while(vis[now])now++;}
for(int i=0;i<k;i++)printf("%c",tmp[i]);puts("");
}
int main()
{
scanf("%d",&T);
while(T--)solve();
}
...
然后发现...可以搜索...
而且代码巨简单.jpg
D
分析一波性质发现:
在每个位置的两侧同时出现一个能输给他的,他就一定有可能能赢...
或者,在他的某一侧同时没有输给他的和赢他的,他也一定有可能能赢...
然后set+树状数组就行
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <bitset>
#include <set>
using namespace std;
#define N 200005
struct BIT
{
int s[N];
void fix(int x,int op){for(;x<N;x+=x&-x)s[x]+=op;}
int find(int x){int ret=0;for(;x;x-=x&-x)ret+=s[x];return ret;}
int get(int l,int r){return find(r)-find(l-1);}
}b[3];
set<int>s[3];
int a[128],n,Q;
char str[N],opt[3];
int calc()
{
int ans=0;
for(int i=0;i<3;i++)
{
if(s[(i+1)%3].empty()){ans+=s[i].size();continue;}
if(s[(i+2)%3].empty())continue;
int L=*s[(i+2)%3].begin(),R=*(--s[(i+2)%3].end());
ans+=b[i].get(L,R);
int X=*s[(i+1)%3].begin(),Y=*(--s[(i+1)%3].end());
ans+=b[i].find(min(L,X)-1)+b[i].get(max(R,Y)+1,n);
}
return ans;
}
int main()
{
a['R']=0;a['P']=1;a['S']=2;
scanf("%d%d%s",&n,&Q,str+1);
for(int i=1;i<=n;i++)s[a[str[i]]].insert(i),b[a[str[i]]].fix(i,1);
printf("%d\n",calc());
while(Q--)
{
int x;scanf("%d%s",&x,opt);
s[a[str[x]]].erase(x);b[a[str[x]]].fix(x,-1);
str[x]=opt[0];
s[a[str[x]]].insert(x),b[a[str[x]]].fix(x,1);
printf("%d\n",calc());
}
}
E
非常有意思的树状数组优化DP,非常厉害的数数题...
按照正常思路,求一个当前一定比它小的个数,然后递归下去可能比它小的个数...
然后求出一个$i$个数组成一个排列,给你$i$个数有$j$个在这$i$个数里出现过,然后错排的方案数...
然后把这个东西求出来之后,用树状数组维护这一行和上一行的状态,就可以知道有多少个数在$i$个里出现过了...以及当前位置有多少个比它小的数的个数...
然后就完事了...
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <iostream>
#include <bitset>
using namespace std;
#define N 2005
#define ll long long
#define mod 998244353
int a[N][N],f[N][N],n,fac[N],ans,g[N],c[N],s[N],pf[N],vis1[N],vis2[N];
void fix(int *a,int x,int op){for(;x<=n;x+=x&-x)a[x]+=op;}
int find(int *a,int x){int ret=0;for(;x;x-=x&-x)ret+=a[x];return ret;}
void init(){memset(c,0,sizeof(c));memset(s,0,sizeof(s));}
int main()
{
scanf("%d",&n);fac[0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);g[1]=0,g[2]=1;
for(int i=1;i<=n;i++)fac[i]=(ll)fac[i-1]*i%mod;
for(int i=3;i<=n;i++)g[i]=(ll)(g[i-1]+g[i-2])*(i-1)%mod;
for(int i=1;i<=n;i++)
{
f[i][0]=fac[i];
for(int j=1;j<i;j++)f[i][j]=((ll)(i-j)*f[i-1][j]+(ll)j*f[i-1][j-1])%mod;
f[i][i]=g[i];
}pf[0]=1;
for(int i=1;i<=n;i++)pf[i]=(ll)pf[i-1]*g[n]%mod;
init();
for(int i=n;i;i--)
{
fix(c,a[1][i],1);
ans=(ans+(ll)find(c,a[1][i]-1)*fac[n-i]%mod*pf[n-1])%mod;
}
for(int i=2;i<=n;i++)
{
init();memset(vis1,0,sizeof(vis1));memset(vis2,0,sizeof(vis2));
for(int j=n;j;j--)
{
vis2[a[i][j]]=1;
if(!vis1[a[i][j]])fix(c,a[i][j],1);
else fix(s,a[i][j],1);
int cnt=find(s,n);
ans=(ans+(ll)find(c,a[i][j]-1)*f[n-j][cnt]%mod*pf[n-i])%mod;
if(cnt)ans=(ans+(ll)find(s,a[i][j]-1)*f[n-j][cnt-1]%mod*pf[n-i])%mod;
if(a[i][j]>a[i-1][j]&&vis2[a[i-1][j]])
ans=(ans-(ll)f[n-j][cnt]*pf[n-i])%mod;
if(!vis2[a[i-1][j]])vis1[a[i-1][j]]=1;
else
{
vis1[a[i-1][j]]=1;
fix(c,a[i-1][j],-1);
fix(s,a[i-1][j],1);
}
}
}
printf("%d\n",(ans+mod)%mod);
}
Codeforces round 1086的更多相关文章
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
- cf之路,1,Codeforces Round #345 (Div. 2)
cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅..... ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- Codeforces Round #262 (Div. 2) 1003
Codeforces Round #262 (Div. 2) 1003 C. Present time limit per test 2 seconds memory limit per test 2 ...
- Codeforces Round #262 (Div. 2) 1004
Codeforces Round #262 (Div. 2) 1004 D. Little Victor and Set time limit per test 1 second memory lim ...
- Codeforces Round #370 - #379 (Div. 2)
题意: 思路: Codeforces Round #370(Solved: 4 out of 5) A - Memory and Crow 题意:有一个序列,然后对每一个进行ai = bi - bi ...
- Codeforces Round #371 (Div. 1)
A: 题目大意: 在一个multiset中要求支持3种操作: 1.增加一个数 2.删去一个数 3.给出一个01序列,问multiset中有多少这样的数,把它的十进制表示中的奇数改成1,偶数改成0后和给 ...
随机推荐
- js取数组最大值的四种方式
var arr = [7,2,0,-3,5];1.apply()应用某一对象的一个方法,用另一个对象替换当前对象 var max = Math.max.apply(null,arr);console. ...
- Jdk1.8中的HashMap实现原理
HashMap概述 HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变. HashM ...
- Redis常用数据类型和事物以及并发
Redis数据类型 基本类型(String int): 如 set key value .get key 等 所有命令都是按照 key value keys * 可以将全部数据列出,其中后面的 &qu ...
- tcp/ip协议详解
1. 概念介绍 互联网协议(Internet Protocol Suite)是一个网络通信模型,以及一整个网络传输协议家族,为互联网的基础通信架构.它常被通称为 TCP/IP 协议族(英语:TCP/I ...
- MappedByteBuffer
计算机内存管理 原文链接 https://www.cnblogs.com/guozp/p/10470431.html MMC:CPU的内存管理单元. 物理内存:即内存条的内存空间. 虚拟内存:计算机系 ...
- 批量执行工具PSSH详解
批量执行工具PSSH详解 pssh是一个python编写可以在多台服务器上执行命令的工具,同时支持拷贝文件,是同类工具中很出色的,使用必须在各个服务器上配置好密钥认证访问. 安装pssh包 yum 安 ...
- .NET Core微服务之基于Polly+AspectCore实现熔断与降级机制
Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.熔断.降级与AOP 1.1 啥是熔断? 在广义的解释中,熔断主要是指为控制股票.期货或其他金融衍生产品的交易风险,为其单日价格波动幅度 ...
- TabLayoutViewPagerDemo【TabLayout+ViewPager可滑动】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用TabLayout搭配ViewPager实现可滑动的顶部选项卡效果. 效果图 代码分析 1.演示常规的设置. 2.通过自定义Vi ...
- 一个box-sizing: border-box和felx混合使用中遇到的问题
之前在项目中遇到一个布局上很趣的问题(也可能是笔者才疏学浅,哈哈).布局大概是这样的: 外层包裹器:采用flex布局,并指定内部子弹性盒子元素水平显示 侧边栏:flex盒子的子元素,可收起和展开.展开 ...
- Docker部署Zabbix监控MariaDB主从同步(Percona Monitoring Plugins for Zabbix)
一.安装Docker并部署Zabbix 建议先配置清华大学的docker-ce yum源,速度有保障:清华大学repo源 1.Zabbix Server节点配置 部署环境: [root@server0 ...