2017/8/11 考试吐槽

2017 8 11 得分:50

莫名心酸……自己垃圾成了这个样子……我说不出来了……(默默擦去眼角的一滴泪……)

A、Travel

题意:给出一张无向连通图,求出从一个点只走边权小于定值的边的数量。

我差点哭出声……但是忍住了……不忍了……哇…………………………………………………………/(ㄒoㄒ)/~~不说了满满的都是泪……

本来考试的时候,成功想出来了这个东西可以倒过来看,看做一个不断向图里面插边的过程,可以离线存下询问,按从小到大顺序加边,适时进行询问,而维护连通块大小也可以使用并查集进行。

然而少写了一对括号……哇……………………………………………………………………………………

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<deque>
 6 using namespace std;
 7 const int maxn=100005;
 8 struct node
 9 {
10     int from,to,dis;
11     bool operator <(const node &b)const
12     {
13         return dis<b.dis;
14     }
15 }edge[maxn<<2];
16 int tot,n,m,q;
17 void addedge(int u,int v,int w)
18 {
19     edge[++tot]=(node){u,v,w};
20 }
21 int fa[maxn],siz[maxn];
22 int getfa(int x)
23 {
24     return x==fa[x]?x:fa[x]=getfa(fa[x]);
25 }
26 void unionn(int x,int y)
27 {
28     x=getfa(x),y=getfa(y);
29     if(x!=y)
30     {
31         if(siz[x]<siz[y])swap(x,y);
32         siz[x]+=siz[y];
33         fa[y]=x;
34     }
35 }
36 int id[maxn],st[maxn],length[maxn],val[maxn];
37 int cmp(const int &a,const int &b)
38 {
39     return length[a]<length[b]||(length[a]==length[b]&&st[a]<st[b]);//就是这个!
40 }
41 int haha()
42 {
43     //freopen("travel0.in","r",stdin);
44     //freopen("travel.out","w",stdout);
45     scanf("%d%d%d",&n,&m,&q);
46     //cout<<m<<endl;
47     for(int i=1;i<=n;i++)siz[i]=1,fa[i]=i;
48     for(int i=1;i<=m;i++)
49     {
50         int x,y,z;scanf("%d%d%d",&x,&y,&z);
51         addedge(x,y,z);
52     }
53     sort(edge+1,edge+m+1);
54     //cout<<endl;
55     for(int i=1;i<=q;i++)
56     {
57         id[i]=i;
58         scanf("%d%d",&st[i],&length[i]);
59     }
60     sort(id+1,id+q+1,cmp);
61     //for(int i=1;i<=q;i++)cout<<length[id[i]]<<" ";
62     //cout<<endl;
63     int cur1=1,cur2=1;
64     for(;cur2<=q;)
65     {
66         int curlength=length[id[cur2]];
67         while(edge[cur1].dis<=curlength&&cur1<=m)
68         {
69             int u=edge[cur1].from,v=edge[cur1].to;
70             unionn(u,v);
71             cur1++;
72         }
73         while(length[id[cur2]]==curlength&&cur2<=q)
74         {
75             val[id[cur2]]=siz[getfa(st[id[cur2]])];
76             cur2++;
77         }
78         //cout<<val[id[cur2-1]]<<endl;
79     }
80     //while(1);
81     for(int i=1;i<=q;i++)printf("%d
",val[i]);
82 }
83 int sb=haha();
84 int main(){;}
A

B、钟

题意:帮派打架,一个人破产就退出,求出留到最后的帮派。

不得不说这个破时限要搞大事情……

在本地看到$10^6$这个东西下意识想到了$O(n)$利器单调栈,然而自己研究了一会并没有发现这个东西有什么单调性。写了半天,补了半天锅交上去了。

结果交上去才发现:卧槽时限$14s$!14s!14s!

早知道这个东西我不就打暴力了嘛……然后正解神$TM$就是暴力……阿了那个改了时限然后不在文件里更新的人……这几天第几回了……

其实正解不是暴力……然而正解被卡了……

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<set>
 6 using namespace std;
 7 const int maxn=(int)1e6+5,maxc=105;
 8 void fastread(int &x)
 9 {
10     x=0;char c=getchar();int f=1;
11     while(c<'0'||c>'9')
12     {
13         if(c=='-')f=-1;
14         c=getchar();
15     }
16     while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
17     x*=f;
18 }
19 struct node
20 {
21     int pos,tim,cost,res,last;
22     bool operator<(const node &b)const
23     {
24         return tim<b.tim||(tim==b.tim&&pos<b.pos);
25     }
26 }now[maxn];
27 int n,c,fight[maxc][maxc],ord[maxn],Left[maxn],Right[maxn],cnt[maxc],kind,a[maxn];
28 int haha()
29 {
30     //freopen("clock.in","r",stdin);
31     //freopen("clock.out","w",stdout);
32     fastread(c),fastread(n);
33     for(int i=1;i<=c;i++)
34         for(int j=1;j<=c;j++)fastread(fight[i][j]);
35     for(int i=1;i<=n;i++)fastread(ord[i]);
36     for(int i=1;i<=n;i++)
37     {
38         Left[i]=i-1,Right[i]=i+1;a[i]=1;
39         cnt[ord[i]]++;if(cnt[ord[i]]==1)kind++;
40     }
41     Right[0]=1;Right[n]=0;
42     int ans;
43     while(kind>1)
44     {
45         for(int i=Right[0];i;i=Right[i])
46         {
47             int pre=Left[i],nex=Right[i];
48             a[i]+=fight[ord[i]][ord[pre]]+fight[ord[i]][ord[nex]];
49         }
50         for(int i=Right[0];i;i=Right[i])
51             if(a[i]<=0)
52             {
53                 int pre=Left[i],nex=Right[i];
54                 Right[pre]=nex;Left[nex]=pre;
55                 cnt[ord[i]]--;if(!cnt[ord[i]])kind--;
56             }
57     }
58     for(int i=1;i<=c;i++)
59         if(cnt[i])
60         {
61             printf("%d
",i);
62             return 0;
63         }
64 }
65 int sb=haha();
66 int main(){;}
B

C、区间第K大

题意:求出一个数在区间内第$K$大多少次。

懵逼……

完全不记得前几天那道题的做法……直接瞎$JB$搞了$20$分准备交上去。

然后……想象一下我看到每个测试点时限$20s$时的表情……然而暴力的还是不对,只得了$40$分……

正解都扯到$FFT$去了……还是暴力乱搞吧……

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=2005;
 7 int n,q,Rank[maxn][maxn],a[maxn],lmax[maxn][maxn],rmax[maxn][maxn],lcnt[maxn],rcnt[maxn];
 8 int haha()
 9 {
10     scanf("%d%d",&n,&q);
11     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
12     a[0]=a[n+1]=0x7fffffff;
13     for(int i=1;i<=n;i++)
14     {
15         lmax[i][0]=rmax[i][0]=i;
16         for(int j=i-1;j>=0;j--)
17             if(a[j]>=a[i])lmax[i][++lcnt[i]]=j;
18         for(int j=i+1;j<=n+1;j++)
19             if(a[j]>a[i])rmax[i][++rcnt[i]]=j;
20     }
21     for(int i=1;i<=n;i++)
22         for(int l=1;l<=lcnt[i];l++)
23         {
24             int q=lmax[i][l-1]-lmax[i][l];
25             for(int r=1;r<=rcnt[i];r++)
26                 Rank[l+r-1][a[i]]+=(rmax[i][r]-rmax[i][r-1])*q;
27         }
28     for(int i=1;i<=q;i++)
29     {
30         int x,y;scanf("%d%d",&x,&y);
31         printf("%d
",Rank[x][y]);
32     }
33 }
34 int sb=haha();
35 int main(){;}
C
原文地址:https://www.cnblogs.com/Loser-of-Life/p/7347584.html