整天自闭。

  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. HDU 3440 House Man(编号排序+线性差分约束跑最短路)

    House Man Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  2. C#构造方法--实例化类时初始化的方法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  3. ISCSI工作流程target和initiator

    随着企业级的数据呈指数增长,传统的集中式存储方案已无法满足其存储要求,因而存储区域网(storage area network,SAN)技术被广泛应用,但其存在距离短.价格贵和构建复杂等不足.基于iS ...

  4. sql语句之随机查询记录和批量插入--基于mysql

    本周遇到了好几次数据库方面的问题,一个是上一篇文章提到的因为要修改数据结构引起的在表间复制字段的需求,另一个就是这篇文章要写的:1,从某个数据表中按照某个字段不重复的随机选取几百条记录:2,然后把这些 ...

  5. 大数据入门第二十三天——SparkSQL(一)入门与使用

    一.概述 1.什么是sparkSQL 根据官网的解释: Spark SQL is a Spark module for structured data processing. 也就是说,sparkSQ ...

  6. sprintboot 和swagger2整合生成文档

    1.创建springboot 工程 2.引入maven依赖 <dependency> <groupId>io.springfox</groupId> <art ...

  7. sql——sql中的各种连接

    现有两张表 tablea 和 tableb     各种连接 1.笛尔卡积 SELECT * FROM TabA a,TabB b where a.id = b.id /*笛尔卡积乘积*/ 返回的结果 ...

  8. 【第三课】Centos 7.x系统安装和网络配置以及远程密钥登录

    目录 一.安装CentOS 7.3 二.配置网络 1.使用dhclient命令自动获取ip地址 2.使用ip addr或ifconfig命令查看网卡信息 3.使用route命令查看路由信息 4.通过修 ...

  9. Selenium-ActionChainsApi接口详解

    ActionChains 有时候我们在通过Selenium做UI自动化的时候,明明能够在DOM树内看到这个元素,但是我在通过driver click.sendkey的时候,就是点击不到或无法输入字符串 ...

  10. 未能正确加载包“Microsoft.Data.Entity.Design.Package.MicrosoftDataEntityDesignPackage(转)

    版权声明:作者:jiankunking 出处:http://blog.csdn.net/jiankunking 本文版权归作者和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显 ...