整天自闭。

  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. DB-Engines Ranking

    DB-Engines Ranking trend chart The DB-Engines Ranking ranks database management systems according to ...

  2. IDEA创建Scala项目

    一.安装插件 见Scala入门篇 二.新建项目 选择new project,其中SBT相当于精简版的maven,其他的待补充.这里选择IDEA 填写信息,选择Scala SDK 在src目录下新建Sc ...

  3. MFC CTreeCtrl运用

    CTreeCtrl运用 删除无效资源 递归的运用 自写遍历目录函数 递归遍历所有子目录 一.删除无效资源 .打开资源文件 .找到无效链接删掉 二.自写遍历目录函数 CFileFind findfile ...

  4. mfc 重载赋值运算符

    重载赋值运算符= 一.重载运算符格式 返回类型 operator 运算符 (参数); 如: bool operator=(char*s); int operator>(char*s); bool ...

  5. 解决重启centos后resolv.conf总被清空的问题

    解决重启centos后resolv.conf总被清空的问题 最近在机器上装了虚拟机virtualbox,然后安装了centos6.4,安装了免费主机控制面板virtualmin,在本地机器上搭建测试网 ...

  6. GATT scan的流程

    BLE scan 在bluedroid的实现中,有两个接口:一个是discovery,一个是ble observe,这两者有什么区别呢? 这里追了一下代码发现,inquiry 是上层调用search ...

  7. centos 6.5 搭建开源堡垒机 Teleport 遇到的问题解决

    几款开源的堡垒机 下面进行 teleport 的安装: https://docs.tp4a.com/install/#11 异常1:libc.so.6: version `GLIBC_2.14' no ...

  8. Unity游戏AI记录(2d横板为例)

    using System.Collections;using System.Collections.Generic;using UnityEngine; public class GeneralPeo ...

  9. PTA (Advanced Level) 1002 A+B for Polynomials

    1002 A+B for Polynomials This time, you are supposed to find A+B where A and B are two polynomials. ...

  10. Linux内核设计与实现(chapter1/2)

    Linux内核简介 Unix从一个失败的多用户操作系统Multics中衍生来的. Unix强大的原因: 简洁 几乎所有的东西都被当做文件来对待,可以通过相同的系统调用接口来进行调用. 因为它是由c语言 ...