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\n",val[i]); 82 } 83 int sb=haha(); 84 int main(){;}
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\n",i); 62 return 0; 63 } 64 } 65 int sb=haha(); 66 int main(){;}
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\n",Rank[x][y]); 32 } 33 } 34 int sb=haha(); 35 int main(){;}
只要是活着的东西,就算是神我也杀给你看。