整天自闭。

  A:有各种讨论方式。我按横坐标排了下然后讨论了下纵坐标单调和不单调两种情况。写了15min也就算了,谁能告诉我printf和cout输出不一样是咋回事啊?又调了10min啊?upd:突然想起来我好像define int long long了

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define int long long
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n;
struct data
{
int x,y;
bool operator <(const data&a) const
{
return x<a.x||x==a.x&&y<a.y;
}
bool operator ==(const data&a) const
{
return x==a.x&&y==a.y;
}
}a[],ans[];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
for (int i=;i<;i++) a[i].x=read(),a[i].y=read();
sort(a,a+);
if (a[].y<=a[].y==a[].y<=a[].y)
{
for (int i=min(a[].y,a[].y);i<=max(a[].y,a[].y);i++) ans[++n].x=a[].x,ans[n].y=i;
for (int i=a[].x;i<=a[].x;i++) ans[++n].x=i,ans[n].y=a[].y;
for (int i=min(a[].y,a[].y);i<=max(a[].y,a[].y);i++) ans[++n].x=a[].x,ans[n].y=i;
for (int i=a[].x;i<=a[].x;i++) ans[++n].x=i,ans[n].y=a[].y;
}
else
{
for (int i=a[].x;i<=a[].x;i++) ans[++n].x=i,ans[n].y=a[].y;
for (int i=min(a[].y,a[].y);i<=max(a[].y,a[].y);i++) ans[++n].x=a[].x,ans[n].y=i;
for (int i=min(a[].y,a[].y);i<=max(a[].y,a[].y);i++) ans[++n].x=a[].x,ans[n].y=i;
for (int i=a[].x;i<=a[].x;i++) ans[++n].x=i,ans[n].y=a[].y;
}
sort(ans+,ans+n+);
n=unique(ans+,ans+n+)-ans-;
cout<<n<<endl;
for (int i=;i<=n;i++) cout<<ans[i].x<<' '<<ans[i].y<<endl;
return ;
}

  B:将权值平均分在叶节点的边上即可。感性证明。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define int long long
#define N 100010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,p[N],t,degree[N];
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read(),m=read();
for (int i=;i<n;i++)
{
int x=read(),y=read();
degree[x]++,degree[y]++;
}
if (n==) {cout<<m;return ;}
int cnt=;
for (int i=;i<=n;i++) if (degree[i]==) cnt++;
printf("%.8f",m*2.0/cnt);
return ;
}

  这个时候就40min了,简直垫底。

  C:考虑让置换后的串在不超过上界的前提下尽量大。一旦某一位不卡上界了,后面就只需要贪心地尽量满足下界。于是在每种字符第一次出现的位置考虑卡与不卡两种情况即可。简直是个思博题。但它是个码农题。不明白意义何在。写的丑的没边了。调了30min,最后3min过非常刺激。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define int long long
#define N 1000010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,k,a[N],b[N],c[N],match[],tmp[];
char s[N];
bool used[];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
T=read();
while (T--)
{
k=read();
scanf("%s",s+);n=strlen(s+);
for (int i=;i<=n;i++) a[i]=s[i]-'a'+;
scanf("%s",s+);
for (int i=;i<=n;i++) b[i]=s[i]-'a'+;
scanf("%s",s+);
for (int i=;i<=n;i++) c[i]=s[i]-'a'+;
memset(match,,sizeof(match));memset(used,,sizeof(used));
bool flag=;
for (int i=;i<=n;i++)
{
if (!match[a[i]])
{
for (int x=c[i]-;x>=;x--)
if (!used[x])
{
for (int j=;j<=k;j++) tmp[j]=match[j];
match[a[i]]=x;used[x]=;
bool islim=;flag=;
for (int j=;j<=n;j++)
{
if (match[a[j]]&&match[a[j]]>b[j]) islim=;
if (islim&&match[a[j]]&&match[a[j]]<b[j]) {flag=;break;}
if (!match[a[j]])
{
if (!islim)
{
for (int x=k;x>=;x--)
if (!used[x]) {match[a[j]]=x,used[x]=;break;}
}
else
{
bool f=;
for (int x=k;x>=;x--)
if (!used[x])
{
if (x<b[j]) f=;
else match[a[j]]=x,used[x]=,islim=x==b[j];
break;
}
if (!f) {flag=;break;}
}
}
}
if (flag) break;
memset(used,,sizeof(used));
for (int j=;j<=k;j++)
{
match[j]=tmp[j];
if (match[j]) used[match[j]]=;
}
break;
}
if (flag) break;
if (!used[c[i]]) match[a[i]]=c[i],used[c[i]]=;
else break;
}
if (match[a[i]]&&(match[a[i]]<c[i]||match[a[i]]==c[i]&&i==n))
{
//for (int j=1;j<=k;j++) tmp[j]=match[j];
bool islim=;flag=;
for (int j=;j<=n;j++)
{
if (match[a[j]]&&match[a[j]]>b[j]) islim=;
if (islim&&match[a[j]]&&match[a[j]]<b[j]) {flag=;break;}
if (!match[a[j]])
{
if (!islim)
{
for (int x=k;x>=;x--)
if (!used[x]) {match[a[j]]=x,used[x]=;break;}
}
else
{
bool f=;
for (int x=k;x>=;x--)
if (!used[x])
{
if (x<b[j]) f=;
else match[a[j]]=x,used[x]=,islim=x==b[j];
break;
}
if (!f) {flag=;break;}
}
}
}
break;
/*if (!flag)
{
memset(used,0,sizeof(used));
for (int j=1;j<=k;j++)
{
match[j]=tmp[j];
if (match[j]) used[match[j]]=1;
}
}*/
}//��ȷ����ijλ������С�ڴ�ĵ�����
if (match[a[i]]&&match[a[i]]>c[i]) break;
if (flag) break;
}
if (flag)
{
printf("YES\n");
for (int i=;i<=k;i++)
if (!match[i])
{
for (int x=;x<=k;x++)
if (!used[x]) {match[i]=x,used[x]=;break;}
}
for (int i=;i<=k;i++) putchar(match[i]+'a'-);printf("\n");
}
else printf("NO\n");
}
return ;
}

  D:考虑什么样的人可能成为冠军。比如这个人出的是石头,那么显然要让出剪刀的尽量去消灭出布的,为了防止剪刀遇上石头又要尽量先让布去消灭其他出石头的。可以发现事实上不用管其他出石头的了,考虑一段石头区间,如果两端有出布的让出布的消灭掉即可,否则其两端都有剪刀,那么这段石头对剪刀没有任何影响。那么只要当前考虑的石头其左右都不是“有出布的但没有出剪刀的”,其就能获得冠军。现在要统计总共有多少人,对石头剪刀布各自算一遍,还是考虑石头,把不合法的石头去掉,显然就是第一个布到第一个剪刀之间和最后一个剪刀到最后一个布之间的(有序)。这玩意好像也不难想而且怎么着也比C好写几倍吧?我能不能向天借个30min啊?

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
#define ll long long
#define int long long
#define N 200010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,m,tree[][N],a[N];
char s[N];
int val(char c){if (c=='R') return ;if (c=='P') return ;if (c=='S') return ;}
void add(int p,int k,int x){while (k<=n) tree[p][k]+=x,k+=k&-k;}
int query(int p,int k){int s=;while (k) s+=tree[p][k],k-=k&-k;return s;}
set<int> q[];
signed main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#endif
n=read(),m=read();
scanf("%s",s+);
for (int i=;i<=n;i++) add(a[i]=val(s[i]),i,),q[val(s[i])].insert(i);
for (int j=;j<=m;j++)
{
if (j){int x=read(),y=val(getc());add(a[x],x,-),add(y,x,);q[a[x]].erase(x),a[x]=y,q[a[x]].insert(x);}
int ans=;
for (int i=;i<;i++)
{
int sc=(i+)%,pp=(i+)%;
if (q[pp].empty()) ans+=query(i,n);
else if (q[sc].empty()) ;
else
{
ans+=query(i,n);
set<int>::iterator it=q[sc].begin();int x=*it;
it=q[sc].end();it--;int y=*it;
it=q[pp].begin();if ((*it)<x) ans-=query(i,x)-query(i,(*it));
it=q[pp].end();it--;if ((*it)>y) ans-=query(i,(*it))-query(i,y);
}
}
printf("%d\n",ans);
}
return ;
}

  E:考虑类似数位dp的做法,枚举在哪一行第一次不卡限制,之后的每一行的方案数显然都是错排数量,那么只要求出该行填法数量就可以了,比较麻烦的是该行同时受到上一行限制。这个东西同样考虑枚举在哪个位置第一次不卡限制,剩下位置的方案数可以表示为f[i][j],即长度为i的排列有j位要求错排(j即两排列的后缀重复元素个数)。当然我们不能枚举第一个不卡限制的位置填什么,而是求一下有多少种填法会使后面的限制(重复元素)减少,树状数组乱搞,这里可能有一些细节问题。最后的问题是如何求f[i][j],直接dp的话可能不太显然,不过有一种无脑的方法,即写出套路的容斥式子,稍加观察就可以发现可以NTT优化一发,CF机子还开了4s当然不虚。注意第一行特殊讨论一下,求出字典序即可。这个题……算了还是比C难(以及难写?)不少。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 2050
#define P 998244353
#define inv3 332748118
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int n,a[N][N],wrong[N],fac[N],inv[N],tree[N],f[N][N<<],u[N<<],lim[N],id[N],r[N<<],ans;
bool flag1[N],flag2[N];
void ins(int k){while (k<=n) tree[k]++,k+=k&-k;}
int query(int k){int s=;while (k) s+=tree[k],k^=k&-k;return s;}
int ksm(int a,int k)
{
int s=;
for (;k;k>>=,a=1ll*a*a%P) if (k&) s=1ll*s*a%P;
return s;
}
int C(int n,int m){return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
void DFT(int *a,int n,int g)
{
for (int i=;i<n;i++) if (i<r[i]) swap(a[i],a[r[i]]);
for (int i=;i<=n;i<<=)
{
int wn=ksm(g,(P-)/i);
for (int j=;j<n;j+=i)
{
int w=;
for (int k=j;k<j+(i>>);k++,w=1ll*w*wn%P)
{
int x=a[k],y=1ll*w*a[k+(i>>)]%P;
a[k]=(x+y)%P,a[k+(i>>)]=(x-y+P)%P;
}
}
}
}
void mul(int *a,int *b,int n)
{
for (int i=;i<n;i++) r[i]=(r[i>>]>>)|(i&)*(n>>);
DFT(a,n,),DFT(b,n,);
for (int i=;i<n;i++) a[i]=1ll*a[i]*b[i]%P;
DFT(a,n,inv3);int t=ksm(n,P-);
for (int i=;i<n;i++) a[i]=1ll*a[i]*t%P;
}
void pre()
{
wrong[]=;wrong[]=;for (int i=;i<=n;i++) wrong[i]=1ll*(i-)*(wrong[i-]+wrong[i-])%P;
wrong[]=;for (int i=;i<=n;i++) wrong[i]=1ll*wrong[i-]*wrong[n]%P;
fac[]=;for (int i=;i<=n;i++) fac[i]=1ll*fac[i-]*i%P;
inv[]=inv[]=;for (int i=;i<=n;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
for (int i=;i<=n;i++) inv[i]=1ll*inv[i-]*inv[i]%P;
for (int i=;i<=n;i++)
{
int t=;while (t<=(i<<)) t<<=;
for (int j=i+;j<t;j++) u[j]=;
for (int j=;j<=i;j++) u[j]=j&?P-inv[j]:inv[j],u[j]=1ll*u[j]*fac[i-j]%P,f[i][j]=inv[j];
mul(f[i],u,t);
for (int j=;j<=i;j++) f[i][j]=1ll*f[i][j]*fac[j]%P;
}
}
int calc(int *a)
{
memset(tree,,sizeof(tree));int s=;
for (int i=;i<=n;i++)
s=(s+1ll*fac[n-i]*(a[i]--query(a[i])))%P,ins(a[i]);
return s;
}
int calc(int *a,int *b)
{
memset(tree,,sizeof(tree));int s=;
memset(flag1,,sizeof(flag1));memset(flag2,,sizeof(flag2));lim[n+]=;
flag2[b[n]]=;
for (int i=n;i>=;i--)
{
lim[i]=lim[i+];
flag1[a[i]]=;if (flag2[a[i]]) lim[i]++;
id[i]=query(b[i]),ins(b[i]);
if (a[i]<b[i]&&flag2[a[i]]) id[i]--;
flag2[b[i-]]=;if (flag1[b[i-]]) lim[i]++;
}
memset(flag1,,sizeof(flag1));memset(flag2,,sizeof(flag2));
memset(tree,,sizeof(tree));
for (int i=n;i>=;i--)
{
int x=query(b[i]-);
s=(s+1ll*x*f[n-i][lim[i+]-])%P;
s=(s+1ll*(id[i]-x)*f[n-i][lim[i+]])%P;
flag1[a[i]]=;if (flag2[a[i]]) ins(a[i]);
flag2[b[i]]=;if (flag1[b[i]]) ins(b[i]);
}
return s;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("e.in","r",stdin);
freopen("e.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
a[i][j]=read();
pre();
ans=1ll*calc(a[])*wrong[n-]%P;
for (int i=;i<n;i++)
{
int x=calc(a[i],a[i+]);
ans=(ans+1ll*x*wrong[n-i-])%P;
}
cout<<ans;
return ;
}

  我也不知道为什么还能涨分。result:rank 208 rating +7

Codeforces Round #528 Div. 1 自闭记的更多相关文章

  1. Educational Codeforces Round 58 Div. 2 自闭记

    明明多个几秒就能场上AK了.自闭. A:签到. #include<iostream> #include<cstdio> #include<cmath> #inclu ...

  2. Codeforces Round #554 (Div. 2)自闭记

    A 签到 #include<bits/stdc++.h> using namespace std; ],t[],ans; int main() { scanf("%d%d&quo ...

  3. Codeforces Round #545 Div. 1自闭记

    A:求出该行该列各有多少个比其小的取max,该行该列各有多少个比其大的取max,加起来即可. #include<iostream> #include<cstdio> #incl ...

  4. Codeforces Round #526 Div. 1 自闭记

    日常猝死. A:f[i]表示子树内包含根且可以继续向上延伸的路径的最大价值,统计答案考虑合并两条路径即可. #include<iostream> #include<cstdio> ...

  5. Codeforces Round #567 (Div. 2)自闭记

    嘿嘿嘿,第一篇文章,感觉代码可以缩起来简直不要太爽 打个div2发挥都这么差... 平均一题fail一次,还调不出错,自闭了 又一次跳A开B,又一次B傻逼错误调不出来 罚时上天,E还傻逼了..本来这场 ...

  6. Codeforces Round #530 Div. 1 自闭记

    A:显然应该让未确定的大小尽量大.不知道写了啥就wa了一发. #include<iostream> #include<cstdio> #include<cmath> ...

  7. Codeforces Round #525 Div. 2 自闭记

    A:签到. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> ...

  8. Codeforces Round #528 (Div. 2)题解

    Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...

  9. (AB)Codeforces Round #528 (Div. 2, based on Technocup 2019 Elimination Round

    A. Right-Left Cipher time limit per test 1 second memory limit per test 256 megabytes input standard ...

随机推荐

  1. java的myeclipse,java页面改动默认的javadoc方法

    在项目中右键点击新建class文件,在弹出的框中选择"here" 勾上enable project specific settings 选择comments中的types然后点击e ...

  2. Winniechen’s test1

    https://winniechen.cn/wp-content/uploads/2018/08/Winniechens_test_1.rar 放水练习赛,主要考察最短路,DP,状态压缩等知识点 题解 ...

  3. Windows Server2003 IIS服务器安全配置整理

    一.系统的安装   1.按照Windows2003安装光盘的提示安装,默认情况下2003没有把IIS6.0安装在系统里面.2.IIS6.0的安装 开始菜单—>控制面板—>添加或删除程序—& ...

  4. Sqlite 快速批量插入数据 测试

    public static int insertDbBatch() { string sql = ""; SQLiteConnection conn = new SQLiteCon ...

  5. python基础学习1-流程控制和判断

    python for循环和 if流程控制用法 Ages=22 for i in range(10): inputAges = int(input("输入年龄")) if input ...

  6. Ubuntu+Qt+OpenCV+FFMPEG环境搭建

    基于ubuntu16.04下opencv3.2安装配置 Ubuntu16.04下安装FFmpeg(超简单版) Qt编译后提示: /usr/bin/ld: 找不到 -lGL 安装libGL: sudo ...

  7. 【转载】VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径

    原文:http://www.cnblogs.com/lidabo/archive/2012/05/29/2524170.html 说明 $(RemoteMachine) 设置为“调试”属性页上“远程计 ...

  8. 蓝牙重启case之:hardware error

    蓝牙的通信分为host和controller,host端发送数据和命令到controller,controller 上传event以及数据到host端,这要求上下两端的通信要求状态一致性. 当发生状态 ...

  9. python3获取主机名、主机IP

    python3可以通过socket模块获取主机名及主机IP 代码如下: *********************************************************** 学习永远 ...

  10. MQ见解

    MQ 消息队列是系统级.模块级的通信.RPC是对象级.函数级通信. 1) 什么是推模式,什么是拉模式 2) 有没有消息丢失情况,如何防止 3) MQ用来解决什么问题 4) 你们用的什么MQ,为什么要用 ...