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)的最小正整数解. 格式 输入格式 输入只有一 ...
随机推荐
- Python接口测试-以&连接拼接字典数据(get中url请求数据)
get请求的utl数据是这样的,例如:/banner/findBanner?bannerType=1&_=1556107073181 ''' 1-banner图-banner/findBann ...
- shift and add算法相关
1.超分辨率 非均匀插值 Farsiu S, Robinson D, Milanfar P. Robust shift and add approach to superresolution[J]. ...
- 怎么彻底关闭卸载删除Cortana小娜进程,最简单
原文地址:https://jingyan.baidu.com/article/90bc8fc8be67bcf653640cfa.html Win10中的Cortana是微软开发的一款个人AI助理,集聊 ...
- HTTP请求协议中请求报文(Request Headers)跟响应报文(Response Headers)的简单理解
背景 今儿个一新来的应届生问我,开发模式中所看到的web请求的请求头里的属性怎么理解,我便根据自己的经验随便拉开一个请求跟他聊了起来,顺便自己记录下文字版,以后再有交流直接发地址给他就好了,嘻嘻,机智 ...
- PCL中有哪些可用的PointT类型(3)
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=268 PointXYZRGBNormal - float x, y, z, ...
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-5.HttpClient4.x工具获取使用
笔记 5.HttpClient4.x工具获取使用 简介:讲解httpClient4.x相关依赖,并封装基本方法. 1.加入依赖 <dependency> ...
- StringJoiner,StringBuffer的一些lamada写法
public String friendlyText(List data) { if(CollectionUtils.isEmpty(data)) { return "[]"; } ...
- linux下的缓存机制buffer、cache、swap
一.缓存机制介绍 在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果 ...
- Servlet(1):基础概念/最简实例
Servlet 生命周期(1) init()方法初始化Servlet对象 它在第一次创建Servlet时被调用,在后续每次不同用户请求时不再调用.(2) service()方法来处理客户端的请求 ...
- 资深技术Leader曹乐:如何成为技术大牛
From: https://mp.weixin.qq.com/s/QaBTm_9AJC01Isr3LLR3aw 原创: 曹乐 公众号: 再成长一次 看了下面这篇文章的话,应该会有收获. 虽然排版不好, ...