NOIp2017——追求那些我一直追求的

谨以此祭奠我即将爆炸的NOIP2017.

$Mingqi\_H\ \ 2017.09.24$

Day -47

突然发现半年来自己从来没有写对过SPFA,最近几天才发现自己的板子一直是错的...赶紧找个例题修一下板子:

 1 #include
 2 #include
 3 #include
 4 using namespace std;
 5 const int maxn = 1e6+10;
 6 struct Edge{
 7     int u,v,w;
 8 }edge[maxn*2];
 9 int head[maxn];
10 int cnt;
11 int dis[maxn],vis[maxn];
12 int m,n;
13 inline void add(int u,int v,int w)
14 {
15     edge[++cnt].u=head[u];
16     edge[cnt].v=v;
17     edge[cnt].w=w;
18     head[u]=cnt;
19     return;
20 }
21 void spfa(int p)
22 {
23     memset(dis,0x3f,sizeof(dis));
24     memset(vis,0,sizeof(vis));
25     int cur,nxt,v;
26     queue<int> q;
27     while(!q.empty())
28         q.pop();
29     q.push(p),vis[p]=true;
30     dis[p]=0;
31     while(!q.empty())
32     {
33         cur=q.front(),q.pop(),vis[cur]=false;
34         for(int i=head[cur];i;i=edge[i].u)
35         {
36             v=edge[i].v;
37             if(dis[p]+edge[v].w<dis[v])
38             {
39                 dis[v]=dis[p]+edge[v].w;
40                 q.push(v),vis[v]=true;
41             }
42         }
43     }
44     for(int i=1;i<=m;i++)
45         printf("%d ",dis[i]);
46     printf("\n");
47     return;
48 }
49 int main()
50 {
51     int u,v,w;
52     scanf("%d%d",&m,&n);
53     for(int i=0;i)
54     {
55         scanf("%d%d%d",&u,&v,&w);
56         add(u,v,w);
57     }
58     for(int i=1;i<=m;i++)
59         spfa(i);
60 }

问题:学了这么久了都不会建邻接链表,SPFA加的是点,不是边,链表链表,head数组和edge数组要连起来,第一行是$edge[++cnt].u=head[u];$最后一行是$head[u]=cnt;$永远记住!!!这不是一年前了!!!

你基础不牢啊,吃枣药丸,吃枣药丸,之前还有200多天的时候,你跟现在的水平差不多啊。这100多天你干什么了?!之前不是经常拿到$Rank\ 1$吗?那个你呢?你模拟赛两次四天12道题,分数加起来还没人家一天3道题的多,你会什么啊?会数论吗?之前一直认为自己能拿到$Day2\ T1$的100分,模拟赛那么简单的一道数论题你可是一分都没拿到啊!!!该好好反思一下了!!你不会DP,也就算了,可是你连暴力也不会打,这就说不过去了吧,三四个月前建立的分类,结果到现在也没整理几个题啊,别人的Blogs都有几百道题目了啊!你总共过了有400题吗?!去重之前也仅仅有386道啊!!!还有100多道OJ上的题目,你这一年多干了些什么!

还是从板子开始吧,不能温水煮青蛙了,不能这样下去了。

Kruskal写的也不好,注意不是邻接链表了,是最最普通的数组了,不是邻接表!!!没必要写add_edge!!!写上邻接表的就错了!!!并查集也得背背啊。还有,那个sort对结构体排序还得练一练,都忘得差不多了,必要的话,重新看看OJ上的那几道题目。

#include
#include
using namespace std;
#define maxp 5005
#define maxe 200005
struct Edge{
    int u,v,w;
}edge[maxe];
inline int cmp(Edge a,Edge b){return a.w<b.w;}
int cnt;
int fat[maxp];
inline int find(int x)
{return fat[x]!=x?fat[x]=find(fat[x]):fat[x];}
inline void unionn(int x,int y)
{int fa=find(x),fb=find(y);if(fa!=fb)fat[fa]=fb;}
int n,m;
inline void Kruskal()
{
    sort(edge+1,edge+m+1,cmp);
    int k=0,ans=0;
    for(int i=1;i<=m;i++)
    {
        if(find(edge[i].u)!=find(edge[i].v))
        {
            unionn(edge[i].u,edge[i].v);
            ans+=edge[i].w;
            k++;
        }
    }
    if(k1) printf("orz");
    else printf("%d",ans);
    return;
}
int main()
{
    int u,v,w;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        fat[i]=i;
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
    Kruskal();
    return 0;
}

复习计划:

NOIP范围内所有的知识点,包括数论。重点放在图论、数论、不熟练的知识点(贪心、动规、分治、二分、搜索等),时间:30d.对于其他较少考到的以及高级的内容(中高级数据结构、STL等),短期内全部不涉及,没有时间对那些较难并且没用的东西进行学习了,这不是省选前半年可以停课随便搞的时间了,毕竟马上就要考试了。

保证无论何时、无论有什么情况,每天保证至少学习1h,大周回家至少拿出2h写板子。NOIP前不再学习新的知识了。

Day-45

今天检验之前的SPFA,发现依旧不对……赶紧改过来……

 1 #include
 2 #include
 3 #include
 4 #define maxn 1000001
 5 using namespace std;
 6 struct Edge
 7 {
 8     int u,v,w;
 9 } edge[2*maxn];
10 int head[maxn],cnt;
11 int n,m;
12 int vis[maxn],dis[maxn],cur,nxt;
13 inline void add(int u,int v,int w)
14 {edge[++cnt].u=head[u],edge[cnt].v=v,edge[cnt].w=w,head[u]=cnt;}
15 inline void spfa(int u)
16 {
17     queue<int>q;
18     memset(vis,0,sizeof(vis)),
19     memset(dis,0x3f,sizeof(dis)),
20     dis[u]=0;
21     while(!q.empty())q.pop();
22     vis[u]=true,q.push(u);
23     while(!q.empty())
24     {
25         cur=q.front(),vis[cur]=0,q.pop();
26         for(int i=head[cur]; i; i=edge[i].u)
27         {
28             int v=edge[i].v;
29             if(dis[v]>dis[cur]+edge[i].w)
30             {
31                 dis[v]=dis[cur]+edge[i].w;
32                 if(!vis[v])
33                     vis[v]=1,q.push(v);
34             }
35         }
36     }
37     for(int i=1; i<=m; i++)
38         printf("%d ",dis[i]);
39     printf("\n");
40     return;
41 }
42 int main()
43 {
44     int u,v,w;
45     scanf("%d%d",&m,&n);
46     for(int i=0; i)
47     {
48         scanf("%d%d%d",&u,&v,&w);
49         add(u,v,w);
50     }
51     for(int i=1; i<=m; i++)
52         spfa(i);
53         return 0;
54 }

 ???

 1 #include
 2 #include
 3 #define maxn 1000001
 4 using namespace std;
 5 struct Edge
 6 {
 7     int u,v,w;
 8 } edge[2*maxn];
 9 int head[maxn],cnt;
10 int n,m;
11 int vis[maxn],dis[maxn],cur,nxt;
12 inline void add(int u,int v,int w)
13 {edge[++cnt].u=head[u],edge[cnt].v=v,edge[cnt].w=w,head[u]=cnt;}
14 struct queue{
15     int array[4*maxn];
16     int h,t;
17     inline bool empty(){return h>=t;}
18     inline void push(int x){array[h++]=x;}
19     inline void pop(){t--;}
20     inline int front(){return array[h];}
21     inline void clear(){h=t=0;}
22 }q;
23 inline void spfa(int u)
24 {
25     memset(vis,0,sizeof(vis)),
26     memset(dis,0x3f,sizeof(dis)),
27     dis[u]=0;
28     q.clear();
29     vis[u]=true,q.push(u);
30     while(!q.empty())
31     {
32         cur=q.front(),vis[cur]=0,q.pop();
33         for(int i=head[cur]; i; i=edge[i].u)
34         {
35             int v=edge[i].v;
36             if(dis[v]>dis[cur]+edge[i].w)
37             {
38                 dis[v]=dis[cur]+edge[i].w;
39                 if(!vis[v])
40                     vis[v]=1,q.push(v);
41             }
42         }
43     }
44     for(int i=1; i<=m; i++)
45         printf("%d ",dis[i]);
46     printf("\n");
47     return;
48 }
49 int main()
50 {
51     int u,v,w;
52     scanf("%d%d",&m,&n);
53     for(int i=0; i)
54     {
55         scanf("%d%d%d",&u,&v,&w);
56         add(v,u,w);//无向图 
57         add(u,v,w);
58     }
59     for(int i=1; i<=m; i++)
60         spfa(i);
61     return 0;
62 }
maybe手写队列???

Day-44

今天手打了一遍SPFA,然而边表又建错了...是$edge[++cnt].u=head[u];$不是$edge[cnt++].u=head[u];$

今天复习LCA吧...看起来queue与手写队列效率差不多,对于随机数据两个都差不多,deque更慢了,对于$10^9$的数据效率差了50ms左右。

 1 #include
 2 using namespace std;
 3 #define maxn 500010
 4 int n,m,s,f[maxn][22],deep[maxn],head[maxn],num;
 5 struct node
 6 {
 7     int to,pre;
 8 } e[maxn<<1];
 9 void Insert(int from,int to){e[++num].to=to;e[num].pre=head[from];head[from]=num;}
10 void find_deep(int from,int now,int dep)
11 {
12     f[now][0]=from;
13     deep[now]=dep;
14     for(int i=head[now]; i; i=e[i].pre)
15         if(e[i].to!=from)
16             find_deep(now,e[i].to,dep+1);
17 }
18 void find_father()
19 {
20     for(int j=1; j<=21; j++)
21         for(int i=1; i<=n; i++)
22             f[i][j]=f[f[i][j-1]][j-1];
23 }
24 int get(int a,int delta)
25 {
26     for(int i=0; i<=21; i++)
27         if(delta&(1<f[a][i];
28     return a;
29 }
30 int lca(int a,int b)
31 {
32     if(deep[a]<deep[b]) swap(a,b);
33     a=get(a,deep[a]-deep[b]);
34     if(a==b) return a;
35     for(int i=21; i>=0; i--)
36         if(f[a][i]!=f[b][i])
37             a=f[a][i],b=f[b][i];
38     return f[a][0];
39 }
40 int main()
41 {
42     scanf("%d%d%d",&n,&m,&d);
43     int x,y;
44     for(int i=1; i<=n-1; i++)
45     {
46         scanf("%d%d",&x,&y);
47         Insert(x,y),Insert(y,x);
48     }
49     find_deep(s,s,0);
50     find_father();
51     for(int i=1; i<=m; i++)
52     {
53         scanf("%d%d",&x,&y);
54         printf("%d\n",lca(x,y));
55     }
56     return 0;
57 }

 Day-43

LCA是什么???Tarjan||倍增||树链剖分???

玩一玩树状数组好了。

我什么都不会...

#define lowbit(__x__) (__x__&(-__x__))
//区间查询单点修改不需要差分数组。
//区间查询时需要查询两个端点,调用query(y)-query(x-1)。 
inline int query(int x){int ans=0;for(int i=x;i>0;i-=lowbit(i))ans+=c[i];return ans;}
inline void modify_point(int x,int d){for(int i=x;i<=n;i+=lowbit(x))c[i]+=d;}
//区间修改单点查询需要差分数组。两者有一些不同。
//初始化树状数组时就需要差分处理,用一个pre变量记录前一个元素,然后调用modify(place,x-pre)。
//区间修改直接在差分数组上进行,仅需要修改两个端点即可,调用modify(point,k),modify(point,-k)。
//查询基本相同。 
inline void modify_interval(int x,int d){for(int i=x;i<=n;i+=lowbit(i))a[i]+=d;}

 Day-42

今天忙,坐一整天车,晚上做了作业。

 Day-41

一个弱省蒟蒻,为何到北京?

昨日来京,腰酸背痛。今天开始考试了。然而貌似挂得很惨,T1爆零了2333...还是弱啊,晚上写题解。下午主要讲搜索的技巧。表示双向BFS还是不会。还是去看看搜索大题吧。

Rank 69...看起来T1可以拿到60分左右2333...

Day-40

2333...标日没收了2333...hhh

然而今天题目没区分度...大众分60分...打个表就有了..

不想搞事情了...qbxt真的不是很适合我...回去搞一搞浴谷...

噫...什么时候漏下了一天...好像是回家的那一天???今天应该是Day-39...药丸...赶紧看看LCA与线段树...

据说快停课了...表示好方...

下定决心来一遍LCA...

 1 #include
 2 #include
 3 using namespace std;
 4 const int N = 500100;
 5 int fa[N][25],dep[N];
 6 struct Edge{int to,nxt;}e[N*2];
 7 int head[N],cnt;
 8 inline void add(int u,int v){e[++cnt].to=v,e[cnt].nxt=head[u],head[u]=cnt;}
 9 int n,maxdep,T,rt,top;
10 void build(int u)
11 {
12     for(int i=head[u];i;i=e[i].nxt)
13     {
14         int v=e[i].to;
15         if(v!=fa[u][0])
16         {
17             fa[v][0]=u;
18             dep[v]=dep[u]+1;
19             maxdep=max(maxdep,dep[v]);
20             build(v);
21         }
22     }
23 }
24 inline int LCA(int u,int v)
25 {
26     if(dep[u]<dep[v])swap(u,v);
27     for(int k=top;k>=0;k--)
28         if(dep[fa[u][k]]>=dep[v])
29             u=fa[u][k];
30     if(u==v)
31         return u;
32     for(int k=top;k>=0;k--)
33         if(fa[u][k]!=fa[v][k])
34             u=fa[u][k],v=fa[v][k];
35     return fa[u][0];
36 }
37 int main()
38 {
39     scanf("%d%d%d",&n,&T,&rt);
40     for (int i=1; i)
41     {
42         int u,v;
43         scanf("%d%d",&u,&v);
44         add(u,v),add(v,u);
45     }
46     dep[rt]=1;
47     build(rt);
48     for (; (1<);
49     for (int k=1; k<=top; k++)
50         for (int i=1; i<=n; i++)
51             fa[i][k]=fa[fa[i][k-1]][k-1];
52     while (T--)
53     {
54         int u,v;
55         scanf("%d%d",&u,&v);
56         printf("%d\n",LCA(u,v));
57     }
58     return 0;
59 }
私のLCAテンプレート

只会倍增的我...

Day-39

NOIP模拟赛,Day1难度,20分。

文件文件,引用cstdio库...T1正解都没想出来,太弱啊。

目前的坑:简单的模拟,线段树,dp,文件.

Day-38

NOIP模拟赛,Day2,10分。

文件错误。

目前新增的坑:...太多了...

Day-37

NOIp模拟赛,100分。

蜜汁T1没分,long long炸了。

T2是数据的锅,当然手动拍了一下感觉没什么问题(算法误判率在1‰左右吧),交上竟然A了。

不过今天是数论专场,有dalao AK了,100分也不算高,在50%左右吧。

希望明天rp++,不要出锅。

最后还是因为⑨啊。

Day-31

信息课上来打代码...惨啊...

二区停课了...我们为什么不停...要死啊...

看看LCA什么的...千万别出锅...

另外等着父亲的消息2333...实在不行先暂时通校?鬼知道呢...

昨天去淄博,逛了MUJI的店,然而掉坑里去了...

晚上请假回家,做LCA的板子。线段树什么的还需要复习一下。感觉药丸。

距 NOIp2017 还剩 31 天

Day-30

神TM昨天晚上十一点半睡觉2333...然而写了6k+代码,感觉不错的说...

然而今天快困死了TM...

住校也好不到哪里去据说...

快初赛了...略紧张...虽然知道是买试卷,然而复赛并不有什么把握...

Day-29

今天是历史性的一天。晚上成功申请下来停课了,接下来的日子当然是要好好学习了。后天将面临初赛,RP++!

Day-28

并没有停课,还是回来吧,明天初赛2333.开始背背板子吧。

Day-19

gg...还有3个周...方方方...

Day-12

还有不到2w了,终于停课了,然而两天模拟4场考试完挂。∑=180+0+40+40=260.

Day2 T1T2都想到正解了,然而写挂。哎,自己弱写挂怪谁。

晚上还是好好整理一下吧。

Day-10

还有10d,自己仍然什么都不会,两天模拟赛∑=0+40+0+30=70

已经绝望了。

Day-9

似乎今天被续了1s,加起来得分超过Day-10+Day-11两天的了。

短期内水平可能不会有太多进步了吧。

Day-5

昨天回家翻说说,QBXT校长王彪竟然没有看出来glgjssy,qyhfbqz这一句的含义???蛤蛤蛤蛤蛤蛤。

完蛋了,自己还是什么都不会。这几天打打板子,然后好好整理一下。

1111&&1112那两天考试,当然要抽时间把Magical Mirai 2017补完(似乎今年Vmoe出片比较快???)。

重写了线段树,区间操作47行。然而似乎还是没背过。再看看树状数组。

const int maxn=2*1e7+10;//max node: 5*1e6
long long sum[maxn];//real
long long addv[maxn];//lazy-tag
long long c[maxn/4];
#define mid ((l+r)>>1)
#define lson (o<<1)
#define rson (lson|1)
inline void build(int o,int l,int r)
{
    addv[o]=0;
    if(l==r)sum[o]=c[l];
    else
    {
        build(lson,l,mid);
        build(rson,mid+1,r);
        sum[o]=sum[lson]+sum[rson];
    }
}
inline void push_down(int o,int l,int r)
{
    addv[lson]+=addv[o];
    addv[rson]+=addv[o];
    sum[lson]+=(mid-l+1)*addv[o];
    sum[rson]+=(r-mid)*addv[o];
    addv[o]=0;
}
inline void update(int o,int l,int r,int a,int b,int x)
{
    if(l>=a&&r<=b)
    {
        addv[o]+=x;
        sum[o]+=(r-l+1)*x;
        return;
    }
    if(addv[o])push_down(o,l,r);
    if(a<=mid)update(lson,l,mid,a,b,x);
    if(b>mid)update(rson,mid+1,r,a,b,x);
    sum[o]=sum[lson]+sum[rson];
}
inline long long query(int o,int l,int r,int a,int b)
{
    if(l>=a&&r<=b)return sum[o];
    long long ans=0;
    if(addv[o])push_down(o,l,r);
    if(a<=mid)ans+=query(lson,l,mid,a,b);
    if(b>mid)ans+=query(rson,mid+1,r,a,b);
    return ans;
}

想想线段树还有哪些神奇的操作吧。维护区间最大值最小值什么的也要写。不会ST表可以这样水一下。

Floyd都不会了,重新背一遍吧。

二分的话,前一段时间集训有一大堆,整理一下,总结一下套路吧。

Day-4

今天去竞赛楼整理书,乱七八糟的,丢了一大堆东西,都不知道放在哪里了。rp--。

下午找了一下,竟然在船运传运办公室,东西似乎没丢,rp++.

重做NOIp2016,365分。感觉还好,特别是临时补完复习了期望那些东西,然后成功多得100分。

考试的时候千万别忘记建子文件夹,千万别忘记建子文件夹,千万别忘记建子文件夹!!!

随手写个gcd玩玩。

#include
using namespace std;
int a,b;
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int main()
{
    scanf("%d%d",&a,&b);
    printf("%d",gcd(a,b));
    return 0;
}

线性筛素数:

#include
using namespace std;  
const int N=10000000+10;
bool flag[N];  
int prime[N];
inline void get_prime(int x)  
{
    flag[1]=1;
    int i,j,k=0; 
    for(i=2;i<=x;i++){//注意不能用小于号,否则会WA成SB!!!  
        if(!flag[i])                              
        prime[k++]=i;
        for(j=0;j//注意不能用小于号,否则会WA成SB!!!
            flag[i*prime[j]]=true;              
            if(i%prime[j]==0)               
                break;  
        }  
    }
}
int n,m,q;
int main()
{
    scanf("%d%d",&n,&m);
    get_prime(n);
    for(int i=0;i)
    {
        scanf("%d",&q);
        printf(!flag[q]?"Yes\n":"No\n");
    }
    return 0;  
}

换个背景玩玩,全是蓝色基调的背景太难看了。NOIp后再调整一下博客吧。

void exgcd(int a,int b,int &d,int &x,int &y)
{
    if(!b) {d=a;x=1;y=0;}
    else {gcd(b,a%b,d,y,x);y-=x*(a/b);}
}

当然如果您的浏览器版本不行的话,背景什么的会死的很惨。2333333

Day-3

绝望,已经不知道自己在干什么了。

二区的老师给我们各种压力,明年有5个进队的blahblah。。。

TM你们怎么不先去死。

各种出锅,各种不会,矩阵是什么?

调了一下午矩阵的东西,不知道哪里错了。。。

20分。

还TM考什么NOIp啊...弃疗算了。

回来第二天就要期中考试,考(及)好(格)的概率,不存在的。

我到底在做什么???

Day-2

 已经没救了,模拟都会挂掉。Orz...

Day-1

今天上午考的还可以。200分。继续做课件了。源代码60K+,已经没救了。

晚上继续矩阵乘法,WA成SB...原因竟是忽略了矩阵乘法不具有交换律。

SB啊!!!

矩阵快速幂、乘法:

#include
#include
using namespace std;
typedef vector<long long> vec;
typedef vector matrix;
typedef long long ll;

long long p,q,a1,a2,n,m;

matrix operator *(const matrix &A,const matrix&B)
{
    matrix C(A.size(),vec(B[0].size()));
    for(int i=0;i)
        for(int k=0;k)
            for(int j=0;j0].size();j++)
                C[i][j]=(C[i][j]+A[i][k]*B[k][j])%m;
    return C;
}
matrix pow(const matrix&A,ll n)
{
    matrix B(A.size(),vec(A.size()));
    for(int i=0;i)
        B[i][i]=1;
    while(n)
    {
        if(n&1)B=B*A;
        A=A*A;
        n>>=1;
    }
    return B;
}
int main()
{
    scanf("%lld%lld%lld%lld%lld%lld",&p,&q,&a1,&a2,&n,&m);
    matrix A(2,vec(2));
    A[0][0]=p;A[0][1]=1;
    A[1][0]=q;A[1][1]=0;
    matrix B(1,vec(2));
    B[0][0]=a2,B[0][1]=a1;
    A=pow(A,n-2);
    A=B*A;
    printf("%lld\n",A[0][0]);
    return 0;
}

Day0

 最后一天了。还是什么都不会。

Day1

T1,这是什么题啊,不送分了啊。方方方。5min推出规律,跟暴力拍,哦漏,拍一组挂一组是什么鬼啊。gg,改成暴力。

T2,模拟吧这是。。。疯狂写写写。

(1h later...)MMP什么东西啊,不过样例是什么鬼啊。不写了,开始调试。

(45min. later)MMP还是不过样例啊。完了完了。

T3,?????什么都不会,完蛋了。

(回到RZYZ后:MMP我准考证呢!!!啊啊啊啊药丸药丸啊!!!)

吃晚饭的时候发现xps开不了机(mmp,关键时候掉链子啊),在食堂重置电脑(2333...边充电边重置)。。。

晚上开始颓Magical Marai 2017...没电了就睡了。

Day2

(回到考场老师把准考证还给我了2333...)

T1,三维计算几何???不可做不可做。(读错题flag)随便骗骗分吧(20 pts. get)。

T2,Kruskal重构树,然后DFS计算深度乱搞???不搞了,最后那个数据结构题看起来比较可做啊,先去看看。

T3,先写个暴力,拿30分???

(15min. later)woc...为什么炸了...开始调试。

(30min. later)这,也太容易了吧,随手过样例和大样例啊。

(35min. later)woc...这个暴力炸了,我n和m不分啊,这随机造的数据炸了啊。

(45min. later)终于调完了。考虑一下较高的暴力分吧。

(50min. later)嗯...可以用链表写一下,拿60分吧。

(1.3h later)链表写完了,啊,过了手造的样例。60分应该稳了。

(1.4h later)MMP忘记删if else了,所以刚才的链表实际上是个暴力???删掉看看。

(1.5h later)炸了炸了。交暴力吧,不调了。

转回来做T2,此时距离考试结束还剩40min.

随便写写吧,反正是做不完了。

(35min. later)写完了吧。代码长度1.7k+,非正解啊啊啊啊。不调了,心态爆炸。

颓吧。

11.15

清北数据成绩:100+0+0+0+0+30=130

洛谷数据成绩:100+10+0+20+0+30=160

学军数据成绩:100+0+0+0+0+30=130

完美挂掉。

转载于:https://www.cnblogs.com/TheRoadToAu/p/7588008.html

你可能感兴趣的:(数据结构与算法)