ZROI-Day2比赛解题报告
ZROIDay2-比赛解题报告
版权原因不提供题面信息
序
这几天作息有点鬼畜,虽然昨晚很晚睡但是早上精神还不错,看到题发现T1很友好?T2woc这暴力都好难打?T3多项式?!这样下去比赛会不会出现更多高端操作,恐怕凉凉
A
感谢出题人,暴力好打分又多,正解也不难想,这题基本上部分分都打了一遍
50pts
对于每一个炮将其所在的所在的交叉行(暂且这么说)\(O(1)\) 标记,然后\(O(N^2)\)遍历一遍统计就好了
70pts
核心思想是计算出放一个炮新增的贡献,即它能覆盖的点数减去已经覆盖的点数,最后\(N^2\)减去总和既是答案
拿这部分分还花了不少功夫,终于运用人类智慧找出一些规律,也就是对于一个炮\((x,y)\),它左斜行和右斜行能覆盖的点的个数,然后又发现对于一个确定的左斜行(即确定的\(x+y\)),可以通过\(x,y\)计算出与它有公共点的左斜行的\(x-y\)的相关信息,于是新增一个炮,在他所在的左斜行加上+1标记,加上左斜行覆盖点数,在枚举与左斜行有公共点的右斜行,假设这个右斜行已有标记,则贡献-1。对于右斜行也类似
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <queue>
#include <cmath>
#define ll long long
#define ri register int
#define ull unsigned loong long
const int maxn=100005;
const int inf=0x7ffffffff;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return;
}
int n,m;
int p[maxn<<1],q[maxn<<1];
int cntp=0,cntq=0;
inline void solve_2(){
int x,y;ll ans=0;
while(m--){
read(x),read(y);
if(!p[x+y]){
p[x+y]=1;
cntp++;
if(x+y<=n){
int k=x+y-2;//
ans+=x+y-1;//ok
for(ri i=-k;i<=k;i+=2){
ans-=q[i+n];
}
}
else{
int k=n*2-(x+y);
ans+=k+1;
for(ri i=(x+y)-n*2;i<=n*2-(x+y);i+=2){
ans-=q[i+n];
}
}
}
if(!q[x-y+n]){
q[x-y+n]=1;
cntq++;
if(x-y<=0){
int k=x-y+n-1;
ans+=n+(x-y);
for(ri i=n+1-k;i<=n+1+k;i+=2){
ans-=p[i];
}
}
else{
int k=x-y-n+1;
ans+=n-(x-y);
for(ri i=n+1+k;i<=n+1-k;i+=2){
ans-=p[i];
}
}
}
}
printf("%lld\n",1ll*n*n-ans);
}
int main(){
int x,y;
ll ans=0;
freopen("dat.in","r",stdin);
freopen("bf.out","w",stdout);
read(n),read(m);
solve_2();
return 0;
}
100pts
发现每个左斜行能确定的右斜行的x-y范围是连续的的奇数或偶数,于是用线段树维护标记和区间和,复杂度$O( m $ $log $ \(N)\)
然后鬼畜的是刚码完大样例过不了,以为是奇偶数搞错,魔改了半天后发现有一个判定没写到循环里。。。然后又魔改还是不对,于是开始对拍手动gdb调试,发现有一颗线段树操作的上限因为是x+y要设成\(2n\),查完这个错后据考试结束还有不到半小时,真TM刺激
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <ctime>
#include <queue>
#include <cmath>
#define ll long long
#define ri register int
#define ull unsigned loong long
const int maxn=200015;
const int inf=0x7fffffff;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return;
}
int n,m,N;
bool p[maxn<<1],q[maxn<<1];
int L,R,dta,t;
struct Segment_Tree_1{
int ns[maxn<<2],odds[maxn<<2];//fff是没用的
void update(int now,int l,int r,int fff){//printf("%d****%d\n",l,r);
if(l==r){
if(l&1)odds[now]++;
else ns[now]++;
return ;
}
int mid=(l+r)>>1;
if(t<=mid)update(now<<1,l,mid,fff);
else update(now<<1|1,mid+1,r,fff);
odds[now]=odds[now<<1]+odds[now<<1|1];
ns[now]=ns[now<<1]+ns[now<<1|1];
return ;
}
int odd_query(int now,int l,int r){
if(L<=l&&r<=R){
return odds[now];
}
int mid=(l+r)>>1,ans=0;
if(L<=mid)ans+=odd_query(now<<1,l,mid);
if(mid<R)ans+=odd_query(now<<1|1,mid+1,r);
return ans;
}
int n_query(int now,int l,int r){
if(L<=l&&r<=R){
return ns[now];
}
int mid=(l+r)>>1,ans=0;
if(L<=mid)ans+=n_query(now<<1,l,mid);
if(mid<R)ans+=n_query(now<<1|1,mid+1,r);
return ans;
}
}P;
struct Segment_Tree_2{
int ns[maxn<<1],odds[maxn<<1];
void update(int now,int l,int r,int fff){
if(l==r){
if(l&1)odds[now]++;
else ns[now]++;
return ;
}
int mid=(l+r)>>1;
if(t<=mid)update(now<<1,l,mid,fff);
else update(now<<1|1,mid+1,r,fff);
odds[now]=odds[now<<1]+odds[now<<1|1];
ns[now]=ns[now<<1]+ns[now<<1|1];
return ;
}
int odd_query(int now,int l,int r){
if(L<=l&&r<=R){
return odds[now];
}
int mid=(l+r)>>1,ans=0;
if(L<=mid)ans+=odd_query(now<<1,l,mid);
if(mid<R)ans+=odd_query(now<<1|1,mid+1,r);
return ans;
}
int n_query(int now,int l,int r){
if(L<=l&&r<=R){
return ns[now];
}
int mid=(l+r)>>1,ans=0;
if(L<=mid)ans+=n_query(now<<1,l,mid);
if(mid<R)ans+=n_query(now<<1|1,mid+1,r);
return ans;
}
}Q1,Q2;
inline void solve(){
int x,y;ll ans=0;
while(m--){
read(x),read(y);
if(!p[x+y]){
t=x+y;
P.update(1,1,N,0);
p[x+y]=1;
if(x+y<=n){
int k=x+y-2;
ans+=x+y-1;
int lxl=-k,rr=k;
if(lxl==rr){
L=R=0;
if(q[n])ans--;
}
else {
L=0,R=abs(lxl);
if(R&1)ans-=Q1.odd_query(1,0,n);
else ans-=Q1.n_query(1,0,n);
L=1,R=rr;
if(R&1)ans-=Q2.odd_query(1,1,n);
else ans-=Q2.n_query(1,1,n);
}
}
else{
int k=n*2-(x+y);
ans+=k+1;
int lxl=(x+y)-n*2,rr=n*2-(x+y);
//printf("2--%d ",ans);
if(lxl==rr){
L=R=0;
if(q[n])ans--;//ans-=Q1.n_query(1,0,n);
}
else {
L=0,R=abs(lxl);
if(R&1)ans-=Q1.odd_query(1,0,n);
else ans-=Q1.n_query(1,0,n);
L=1,R=rr;
if(R&1)ans-=Q2.odd_query(1,1,n);
else ans-=Q2.n_query(1,1,n);
}
}
}
if(!q[x-y+n]){
t=x-y;
if(t<=0){
t=abs(t);
Q1.update(1,0,n,1);
}
else {
Q2.update(1,1,n,1);
}
q[x-y+n]=1;
if(x-y<=0){
int k=x-y+n-1;
ans+=n+(x-y);
L=n+1-k,R=n+1+k;
//printf("3--%d ",ans);
if(L&1)ans-=P.odd_query(1,1,N);
else ans-=P.n_query(1,1,N);
}
else{
int k=x-y-n+1;
ans+=n-(x-y);
L=n+1+k,R=n+1-k;
//printf("%d %d\n",L,R);
//printf("4--%d ",ans);
if(R&1)ans-=P.odd_query(1,1,N);
else {
ans-=P.n_query(1,1,N);
}
}
}
}
printf("%lld\n",1ll*n*n-ans);
}
int main(){
int x,y;
ll ans=0;
double st=clock();
freopen("dat.in","r",stdin);
freopen("std.out","w",stdout);
read(n),read(m);N=n*2;
solve();
double ed=clock();
printf("%lf\n",ed-st);
return 0;
}
B
毒瘤期望,n=4的暴力枚举都及其毒瘤,没时间打
题解暂时没搞懂
C
多项式算了吧,考场上暴力模拟感谢出题人拿了40pts,题解推了一大波东西然后什么阶乘卷积。。。
贴一份老师的std
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<string>
#include<assert.h>
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)j;i>=(int)k;i--)
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
using namespace std;
typedef long long LL;
const int P=998244353;
const int G=3;
const int N=310000;
inline int Pow(int a,int b){
int c=1;
for(;b;b>>=1,a=a*1ll*a%P)if(b&1)c=c*1ll*a%P;
return c;
}
int w[2][N];
int rev[N];
inline void fft(int *a,int n,int ff){
rep(i,0,n-1)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int i=1;i<n;i<<=1)
for(int j=0,t=n/(i<<1);j<n;j+=(i<<1))
for(int k=0,l=0;k<i;k++,l+=t){
int x=a[i+j+k]*1ll*w[ff][l]%P;
int y=a[j+k];
a[j+k]=(x+y)%P;
a[i+j+k]=(y+P-x)%P;
}
if(ff==1){
int v=Pow(n,P-2);
rep(i,0,n-1)a[i]=a[i]*1ll*v%P;
}
}
inline void initfft(int n){
rep(i,0,n-1){
int x=i;
int y=0;
for(int k=1;k<n;k<<=1,x>>=1)(y<<=1)|=(x&1);
rev[i]=y;
}
w[0][0]=w[1][0]=1;
int V=Pow(G,(P-1)/n);
int VV=Pow(V,P-2);
rep(i,1,n-1){
w[0][i]=w[0][i-1]*1ll*V%P;
w[1][i]=w[1][i-1]*1ll*VV%P;
}
}
int a[N],n;
int fac[N],inv[N];
int ans[N];
inline void init(int n){
fac[0]=1;rep(i,1,n)fac[i]=fac[i-1]*1ll*i%P;
inv[n]=Pow(fac[n],P-2);per(i,n-1,0)inv[i]=inv[i+1]*1ll*(i+1)%P;
}
int main(){
init(200000);
scanf("%d",&n);
assert(1<=n&&n<=100000);
rep(i,0,n-1){
scanf("%d",&a[i]);
assert(0<=a[i]&&a[i]<P);
}
rep(i,0,n-1)a[i]=a[i]*1ll*fac[i]%P;
initfft(1<<18);
fft(a,1<<18,0);
rep(i,0,(1<<18)-1)a[i]=a[i]*1ll*a[i]%P;
fft(a,1<<18,1);
rep(d,0,n-1){
ans[d]=a[n-1+d];
ans[d]=ans[d]*1ll*Pow(2,d)%P;
ans[d]=ans[d]*1ll*inv[d]%P;
}
rep(i,0,n-1)printf("%d ",ans[i]);
return 0;
}
ZROI-Day2比赛解题报告的更多相关文章
- ZROI Day1 比赛解题报告
ZROI Day1 比赛解题报告 版权原因不提供题面相关信息 序 前天晚上搞得比较晚,然后早上做题很没状态,刚看到T1发现没什么思路就有点慌,赶紧看了看T2,T3, 发现T3暴力很好打,T2想了一想可 ...
- 「雅礼集训 2017 Day2」解题报告
「雅礼集训 2017 Day2」水箱 我怎么知道这种题目都能构造树形结构. 根据高度构造一棵树,在树上倍增找到最大的小于约束条件高度的隔板,开一个 \(vector\) 记录一下,然后对于每个 \(v ...
- 「BZOJ1722」「Usaco2006 Mar」Milk Team Select产奶比赛 解题报告
Milk Team Select 产奶比赛 Description Farmer John's N (\(1 \le N \le 500\)) cows are trying to select th ...
- Day2上午解题报告
预计分数:100+0+60=160 实际分数:100+0+60=160 mmpT1数据错了... T1遭遇 题目描述 你是能看到第一题的 friends呢. —— hja ?座楼房,立于城中 . 第? ...
- Day2下午解题报告
预计分数:100+100+30=230 实际分数:100+100+30=230人品爆发&&智商爆发&&手感爆发 T3数据好水,,要是把数组开大一点的话还能多得10分,, ...
- 【NOIP2015】提高day2解题报告
题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...
- 杭州电子科技大学Online Judge 之 “确定比赛名次(ID1285)”解题报告
杭州电子科技大学Online Judge 之 "确定比赛名次(ID1285)"解题报告 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozh ...
- GX/GZOI2019 day2 解题报告
GX/GZOI2019 day2 解题报告 题目链接 逼死强迫症 旅行者 旧词 t1 逼死强迫症 显然地,记 \(f(i)\) 为长度为 \(i\) 的木板的答案,可得: \(\\\) \[f(i)= ...
- 【未完成0.0】Noip2012提高组day2 解题报告
第一次写一套题的解题报告,感觉会比较长.(更新中Loading....):) 题目: 第一题:同余方程 描述 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. 格式 输入格式 输入只有一 ...
随机推荐
- [学习]sentinel中的DatatSource(一) ReadableDataSource
sentinel是今年阿里开源的高可用防护的流量管理框架. git地址:https://github.com/alibaba/Sentinel wiki:https://github.com/alib ...
- RecyclerView只有一行
RecyclerView只有一行 方法1: 将RecyclerView放在父容器RelativeLayout中,并设置RelativeLayout属性 android:descendantFocu ...
- MySql、PostgreSql、SqlServer三种数据库的造数存储过程实例
主要实例:把临时表tmp_table数据插入到目标表target_table 一.MySql造数存储过程实例 mysql造数 -- 第一步,创建临时表 CREATE TEMPORARY TABLE I ...
- linux下批量转换文件
一.背景 今天遇到windows下文件放置到ubuntu下后,使用vi打开文件,发现每一行结尾总是显示出^M,因此以下是批量转换成linux下格式的方法 二.批量转换成unix下的格式 find . ...
- Docker的镜像制作与整套项目一键打包部署
Dockerfile常用指令介绍 指令 描述 FROM 构建的新镜像是基于哪个镜像.例如:FROM centos:6 MAINTAINER 镜像维护者姓名或邮箱地址.例如:MAINTAINER Mr. ...
- 快速解决设置Android 23.0以上版本对SD卡的读写权限无效的问题
快速解决设置Android 23.0以上版本对SD卡的读写权限无效的问题 转 https://www.jb51.net/article/144939.htm 今天小编就为大家分享一篇快速解决设置And ...
- HttpClient提交数据
用代码模拟浏览器的行为 * 轻量级的开源的框架 * Android在6.0 23 以后移除了httpclient ,所以开发中用的少了 * 编写步骤: 1. 打开浏览器 2. 输入网址 3. 敲回车 ...
- Elasticsearch 空值过滤
参考:https://blog.csdn.net/zhang862520682/article/details/80333196 参考:https://www.jianshu.com/p/7a5d70 ...
- rocksdb wiki文档阅读笔记
由于是英文文档,不做笔记过一阵就忘了,现在把关键点记录到这,开发的时候使用. 具体wiki地址:https://github.com/facebook/rocksdb/wiki 1)Column Fa ...
- JavaScript(5)—— 变量及数据类型
JavaScript和Java在概念和设计方面都是完全不同的语言.JavaScript由Brendan Eich于1995年发明,并于1997年成为ECMA标准.ECMA-262是官方名称.ECMAS ...