NOIP2017总结 & 题解

day1
t1的结论貌似在哪见过,自己稍微验证了一下貌似没记错就没有管了。
t2一道很好(keng)的模拟题
t3自己做题好慢啊,想出来dp打上去最后几分钟才过了大样例,我写的是记忆化搜索,判-1很好判,没时间加上去了可惜了,不过还是自己做题太慢了。然后由于没拍,不确定自己dp对不对,就特判了k=0粘了一个暴力,没想到暴力错了,70变成50...基础不扎实gg

100+100+50=250  好菜啊t3没A掉

day2
t1看完题就开始打,没注意算距离时减一下就变成两倍了会爆long long,但好像数据中z都>=0 ??
t2写完搜索后发现好像可以把所有点深度变成一个n进制数,可以记忆化,不过打完发现n=12要跑10s+,果断删掉换成爆搜。并没有想到如何状压...
t3打完前50分后有一个想法,打完后发现自己想的是错的,于是老老实实写x=1的30分,但耗费了好多时间,没时间打出个数据结构了,于是用了vector,还以为vector有多快,CCF的老爷机上1e5都跑不过,于是t3就挂了,暴力分都没拿全。

100+70+50=220 太菜了

自己做较难题不行,另外noip中还犯了很多知识性错误,主要原因是学的不扎实,没想到第一次也是最后一次noip就这样结束了(本菜鸡去年没考noip)...

题解

day1

t1 答案就是x*y-x-y,证明可以见usaco4.1麦香牛块的题解。

t2 细心模拟即可。

t3 设f(i,j)表示到i点从1~i距离为dis[i]+j的路径个数。对于边u->v,有dis[v]+jv=dis[u]+ju+w(u,v),所以

f(v,jv)=∑ f(u,dis[v]-dis[u]-w(u,v)-jv)  {u | u->v},具体实现可以建出反图记忆化搜索,答案为-1当且仅当同一状态在dfs栈中出现了两次。

day2

t1 模拟。

t2 f1(i,s)表示点i到集合s中点的最小权值,这个可以O(n^2*2^n)处理出。 f2(s1,s2)表示集合s2与s1相连花费的最小代价,O(n*3^n)处理。

f(i,s)表示已经确定了深度<=i的点,且这些点的集合为s,将来要付出的最小代价,枚举下一层选哪些点,f(i,s)=min{ f(i+1,s|s‘)+f2(s,s‘),虽然s‘可能会连向深度<i的点,但如果这样转移了答案会变大,而且如果真要这样连,之前就会转移了的,所以不会计算出错的答案也不会漏掉最优解,这一部分复杂度是O(n*3^n)的。

t3 x=1可以用线段树完成,只需记当前区间未被删除的点的个数,删除第k个数直接查到删去即可,插入同理。

对于一般情况可以对每一排的前m-1个元素建出线段树,然后对最后一列再建出线段树,操作和x=1是一样的,但发现空间开不下,因为这n+1棵线段树最开始叶子节点是等差数列,所以动态开点即可。

附d2t3代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#define P puts("lala")
#define cp cerr<<"lala"<<endl
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
#define ln putchar(‘\n‘)
using namespace std;
typedef pair<int,int> pii;
inline void read(int &re)
{
    char ch=getchar();int g=1;
    while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘)g=-1;ch=getchar();}
    re=0;
    while(ch<=‘9‘&&ch>=‘0‘) re=(re<<1)+(re<<3)+ch-48,ch=getchar();
    re*=g;
}
typedef long long ll;
inline void read(ll &re)
{
    char ch=getchar();ll g=1;
    while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘)g=-1;ch=getchar();}
    re=0;
    while(ch<=‘9‘&&ch>=‘0‘) re=(re<<1)+(re<<3)+ch-48,ch=getchar();
    re*=g;
}

const int N=300050;
int n,m,q;
int rt[N],ch[N*80][2],siz[N*80],sz=0;
ll val[N*80];

ll kth_las(int o,int l,int r,int k)
{
    if(l==r) {return val[o];}
    int mid=l+r>>1;
    if(!ch[o][0])
    {
        ch[o][0]=++sz;ch[o][1]=++sz;
        siz[ch[o][0]]=(siz[o]+1)>>1; siz[ch[o][1]]=siz[o]>>1;
        if(l==mid) val[ch[o][0]]=(ll)l*m;
        if(mid+1==r) val[ch[o][1]]=(ll)r*m;
    }
    if(k<=siz[ch[o][0]]) return kth_las(ch[o][0],l,mid,k);
    else return kth_las(ch[o][1],mid+1,r,k-siz[ch[o][0]]);
}

ll kth(int o,int l,int r,int k,int wh)
{
    if(l==r) {return val[o];}
    int mid=l+r>>1;
    if(!ch[o][0])
    {
        ch[o][0]=++sz;ch[o][1]=++sz;
        siz[ch[o][0]]=(siz[o]+1)>>1; siz[ch[o][1]]=siz[o]>>1;
        if(l==mid) val[ch[o][0]]=(ll)(wh-1ll)*m+l;
        if(mid+1==r) val[ch[o][1]]=(ll)(wh-1ll)*m+r;
    }
    if(k<=siz[ch[o][0]]) return kth(ch[o][0],l,mid,k,wh);
    else return kth(ch[o][1],mid+1,r,k-siz[ch[o][0]],wh);
}

void del(int o,int l,int r,int k)
{
    if(l==r) {siz[o]=0;val[o]=0;return ;}
    int mid=l+r>>1;
    if(k<=siz[ch[o][0]]) del(ch[o][0],l,mid,k);
    else del(ch[o][1],mid+1,r,k-siz[ch[o][0]]);
    siz[o]=siz[ch[o][0]]+siz[ch[o][1]];
}

void ins_las(int o,int l,int r,int x,ll k)
{
    if(l==r) {siz[o]=1;val[o]=k;return ;}
    int mid=l+r>>1;
    if(!ch[o][0])
    {
        ch[o][0]=++sz;ch[o][1]=++sz;
        siz[ch[o][0]]=(siz[o]+1)>>1; siz[ch[o][1]]=siz[o]>>1;
        if(l==mid) val[ch[o][0]]=(ll)l*m;
        if(mid+1==r) val[ch[o][1]]=(ll)r*m;
    }
    if(x<=siz[ch[o][0]]) ins_las(ch[o][0],l,mid,x,k);
    else ins_las(ch[o][1],mid+1,r,x-siz[ch[o][0]],k);
    siz[o]=siz[ch[o][0]]+siz[ch[o][1]];
}

void ins(int o,int l,int r,int x,ll k,int wh)
{
    if(l==r) {siz[o]=1;val[o]=k;return ;}
    int mid=l+r>>1;
    if(!ch[o][0])
    {
        ch[o][0]=++sz;ch[o][1]=++sz;
        siz[ch[o][0]]=(siz[o]+1)>>1; siz[ch[o][1]]=siz[o]>>1;
        if(l==mid) val[ch[o][0]]=(ll)(wh-1ll)*m+l;
        if(mid+1==r) val[ch[o][1]]=(ll)(wh-1ll)*m+r;
    }
    if(x<=siz[ch[o][0]]) ins(ch[o][0],l,mid,x,k,wh);
    else ins(ch[o][1],mid+1,r,x-siz[ch[o][0]],k,wh);
    siz[o]=siz[ch[o][0]]+siz[ch[o][1]];
}

void wj()
{
    freopen("phalanx.in","r",stdin);
    freopen("phalanx.out","w",stdout);
}
int main()
{
    wj();
    int i,j,opt,T;
    read(n);read(m);read(q);
    for(i=1;i<=n;++i)
    {
        rt[i]=++sz;siz[rt[i]]=m-1+q;
        ch[rt[i]][0]=++sz; ch[rt[i]][1]=++sz;
        siz[ch[rt[i]][0]]=(siz[rt[i]]+1)>>1; siz[ch[rt[i]][1]]=siz[rt[i]]>>1;
    }

    rt[n+1]=++sz;siz[rt[n+1]]=n+q;
    ch[rt[n+1]][0]=++sz; ch[rt[n+1]][1]=++sz;
    siz[ch[rt[n+1]][0]]=(siz[rt[n+1]]+1)>>1; siz[ch[rt[n+1]][1]]=siz[rt[n+1]]>>1;

    for(int cas=1;cas<=q;++cas)
    {
        int x,y;read(x);read(y);
        if(y==m)
        {
            ll o=kth_las(rt[n+1],1,n+q,x);
            del(rt[n+1],1,n+q,x);
            printf("%lld\n",o);
            ins_las(rt[n+1],1,n+q,n,o);
        }
        else
        {
            ll o=kth(rt[x],1,m-1+q,y,x);
            del(rt[x],1,m-1+q,y);
            printf("%lld\n",o);//get (x,y)

            ll las=kth_las(rt[n+1],1,n+q,x);//get last element and push to xth row
            ins(rt[x],1,m-1+q,m-1,las,x);

            del(rt[n+1],1,n+q,x);//push o to last column
            ins_las(rt[n+1],1,n+q,n,o);
        }
    }
    return 0;
}
时间: 2024-08-30 15:18:10

NOIP2017总结 & 题解的相关文章

noip2017题解&amp;总结&amp;反省

noip2017是我见过的有史以来最坑爹的一场考试了. 今年北京市考点有一个是我们学校,我还恰好被分到了自己学校(还是自己天天上课的那个教室),于是我同时报了普及提高,一天半的时间都考了. 这次考试总的来说虽然两场都拿了一等奖,但很不满意,从中可以看出我在敲代码学习上还是问题百出. 下面我分两篇来总结. 1.普及组 今年的普及组题目很不良心,我考试的时候周围全是小学生和初一学生...我是少有的几个初三学生中的一个. 普及组的题目,我本来计划ak虐场的,结果被反虐了.不是题不会(每题都是一眼就看出

NOIP2017 题解

QAQ--由于没报上名并没能亲自去,自己切一切题聊以慰藉吧-- 可能等到省选的时候我就没有能力再不看题解自己切省选题了--辣鸡HZ毁我青春 D1T1 小凯的疑惑 地球人都会做,懒得写题解了-- D1T2 时间复杂度 分类讨论+递归就行了,没啥思维含量,略. D1T3 逛公园 这题好劲啊-- D2T1 奶酪 \(O(n^2)\)暴力就行了,水题. D2T2 宝藏 看到数据范围一眼\(O^*(3^n)\)状压DP,其中\(3^n\)来自枚举子集的子集.做法好像有很多,比如ryf的做法就比我快了10倍

NOIP2017题解

改题的过程中发现自己的思路有的很接近正解,但总是出了某些思维方式的偏差,所以或许还是写一写题解的好,毕竟游记都记的是一些乱七八糟的旅行经历和心理感受--正好中午饭前只有强行翘掉的一节课,就欣然划水了. Day1 T1<小凯的疑惑> 得分:100 一道数学题,但是最合适的解法是打表找规律.记a为两个数中较小的一个,我打表的方式是对于每一个要check的数枚举$a$和$b$的系数暴力判断可行性,从$a+1$开始check,如果出现了连续的a个可行解就说明后面的每一个数$x$都可以由$(x-a)+1

TYVJ NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第二轮Day2题解

肝了两题... T1一眼题,分解质因数,找出2的个数和5的个数取min输出 #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> #define ll long long using namespace std; const int maxn=1000010,inf=1e9; int n,m,T; int fac2[m

tyvj NOIP2017金秋冲刺训练营杯联赛模拟大奖赛第一轮Day2题解

上星期打的...题有点水,好多人都AK了 T1排个序贪心就好了 #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<algorithm> #define ll long long using namespace std; const int maxn=500010,inf=1e9; struct poi{int e,s;}a[maxn];

[Luogu 3958] NOIP2017 D2T1 奶酪

NOIP2017 D2T1 奶酪(Luogu 3958) 人生第一篇题解,多多关照吧. 一个比较容易想到的搜索.我用的BFS. 因为涉及到开根,所以记得开double. 首先将所有的球按z值从小到大排序,如果最下方的球与底面相离,或是最上方的球与顶面相离,直接Pass. 接下来预处理,记得先初始化,对于每一组球(i,j),计算两球球心距离是否小于半径×2,用一个bool数组e[i][j]记录i能否到达j,避免BFS时重复计算. 我们会发现,可能不止一个球与底面相切或相交,也可能不止一个球与顶面相

[SinGuLaRiTy] NOIP2017 提高组

[SinGuLaRiTy-1048] Copyright (c) SinGuLaRiTy 2018. All Rights Reserved. NOIP2017过了这么久,现在2018了才找到寒假这么一个空挡来写题解.哎,没办法,谁叫学校抓的紧呢. 序 | Before 这是我的最后一次NOIP. 因为是最后一次的原因吧,考前压力就蛮大的,再加上各种模拟赛,模板练习的轮番轰炸,走进考场时整个人都是“飘飘欲仙”的感觉~ 我的NOIP2017就在这种“飘飘欲仙”的氛围下开始了. 游记 | Blogs

【NOIP2017】列队(Splay)

[NOIP2017]列队(Splay) 题面 洛谷 题解 其实好简单啊... 对于每一行维护一棵\(Splay\) 对于最后一列维护一棵\(Splay\) \(Splay\)上一个节点表示一段区间 每次出去一个人就是把当前的\(Splay\)的一个节点拆分成\(3\)个 然后就很简单了.. 细节比较多.. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #incl

NOIP2017 列队

NOIP2017 列队 题目大意 有一个\(n*m\)的列队方格. 一开始,这个列队中\((i,j)\)的人的编号为\((i-1)m+j\). 每次下达一个指令\((x,y)\),使得\((x,y)\)这个位置的人出列. 然后: 向左看齐,所有人向左填补空位. 向前看齐,所有人向前填补空位. 不难发现两次看齐后空位变到了\((n,m)\),然后令刚才出列的人回到这个位置. 对于依次进行的\(Q\)次指令,你需要输出出列的人的编号. 数据范围:\(n,m,Q \leq 3*10^5\) 前言 NO