2017/07/25 杂题(完全不可做题(划去))选讲

Posted Loser Of Life

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017/07/25 杂题(完全不可做题(划去))选讲相关的知识,希望对你有一定的参考价值。

先膜一发主讲人@Antileaf

真是核平的一天那……大脑已经被蹂躏的死去活来了……

cogs2421 简单的Treap

链接:http://cogs.pro/cogs/problem/problem.php?pid=2421

题意:什么都给你了,建出Treap,输出先序遍历顺序。

实际上只是用了Treap的原则建树……先按照数值大小排序,然后按照建立笛卡尔树方法,维护单调栈,最大的全扔到右儿子去即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=500005;
 7 int n,lc[maxn],rc[maxn],stack[maxn],top,root;
 8 struct node
 9 {
10     int val,fix;
11     bool operator <(const node b)const{
12         return val<b.val;
13     }
14 }a[maxn];
15 void dfs(int root)
16 {
17     printf("%d ",a[root].val);
18     if(lc[root])dfs(lc[root]);
19     if(rc[root])dfs(rc[root]);
20 }
21 int main()
22 {
23     freopen("treap.in","r",stdin);
24     freopen("treap.out","w",stdout);
25     int __size__=128<<20;
26     char *__p__=(char*)malloc(__size__)+__size__;
27     __asm__("movl %0, %%esp\\n"::"r"(__p__));
28     scanf("%d",&n);
29     for(int i=1;i<=n;i++)scanf("%d",&a[i].val);
30     for(int i=1;i<=n;i++)scanf("%d",&a[i].fix);
31     sort(a+1,a+n+1);
32     for(int i=1;i<=n;i++)
33     {
34         stack[top+1]=0;
35         while(top&&a[stack[top]].fix>a[i].fix)top--;
36         lc[i]=stack[top+1];
37         (top?rc[stack[top]]:root)=i;
38         stack[++top]=i;
39     }
40     dfs(root);
41 }
cogs2421

cogs2434 暗之链锁

链接:http://cogs.pro/cogs/problem/problem.php?pid=2434

题意:一个图由一棵树和m条副边形成,只能砍一条树边、一条副边,问有多少种方法使原图不连通。

树上差分啊……找到每条副边,差分处理,然后对每条树边考虑被几条副边覆盖,$x=0$时有m种,$x=1$时就一种。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 const int maxn=100005,maxm=200005;
 8 vector<int>G[maxn],q[maxn];
 9 int n,m,prt[maxn],anc[maxn],a[maxn],x,y,ans;
10 bool vis[maxn];
11 int findroot(int x)
12 {
13     return anc[x]==x?x:(anc[x]=findroot(anc[x]));
14 }
15 void dfs1(int x)
16 {
17     int cnt=G[x].size();
18     anc[x]=x;
19     for(int i=0;i<cnt;i++)
20         if(G[x][i]!=prt[x])
21         {
22             prt[G[x][i]]=x;
23             dfs1(G[x][i]);
24         }
25     vis[x]=1;cnt=q[x].size();
26     for(int i=0;i<cnt;i++)
27         if(vis[q[x][i]])a[findroot(q[x][i])]-=2;
28     anc[x]=prt[x];
29 }
30 void dfs2(int x)
31 {
32     int cnt=G[x].size();anc[x]=x;
33     for(int i=0;i<cnt;i++)
34         if(G[x][i]!=prt[x])
35         {
36             dfs2(G[x][i]);
37             a[x]+=a[G[x][i]];
38         }
39     if(prt[x])
40         if(!a[x])ans+=m;
41         else if(a[x]==1)ans++;
42 }
43 int haha()
44 {
45     freopen("yam.in","r",stdin);
46     freopen("yam.out","w",stdout);
47     scanf("%d%d",&n,&m);
48     for(int i=1;i<n;i++)
49     {
50         scanf("%d%d",&x,&y);
51         G[x].push_back(y);G[y].push_back(x);
52     }
53     for(int i=0;i<m;i++)
54     {
55         scanf("%d%d",&x,&y);
56         if(x==y)continue;
57         a[x]++;a[y]++;
58         q[x].push_back(y),q[y].push_back(x);
59     }
60     dfs1(1);dfs2(1);
61     printf("%d\\n",ans);
62     //while(1);
63 }
64 int sb=haha();
65 int main(){;}
cogs2434

HEOI2017 组合数问题

挖坑……

NOI2016区间

链接:http://cogs.pro/cogs/problem/problem.php?pid=2406

题意:数轴上有n个闭区间,求出m个区间,使至少1个点被这些区间全部包括,并最小化最大区间长度与最小区间长度之差。

真是妙啊……首先对区间按长度排序,对坐标离散化,随后,动态增减区间,线段树动态维护。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 using namespace std;
 6 const int maxn=1000005;
 7 int n,m,x,sm[maxn<<2],mx[maxn<<2],b[maxn],p[maxn],cnt;
 8 struct districts
 9 {
10     int l,r,len;
11 }ques[maxn];
12 int cmp(const int &a,const int &b)
13 {
14     return ques[a].len<ques[b].len;
15 }
16 #define mid ((l+r)>>1)
17 #define lson root<<1,l,mid
18 #define rson root<<1|1,mid+1,r
19 #define lc root<<1
20 #define rc root<<1|1
21 void Modify(int root,int l,int r,int L,int R,int val)
22 {
23     if(L<=l&&r<=R)
24     {
25         mx[root]+=val;
26         sm[root]+=val;
27         return;
28     }
29     if(mid>=L)Modify(lson,L,R,val);
30     if(mid<R)Modify(rson,L,R,val);
31     mx[root]=max(mx[lc],mx[rc])+sm[root];
32 }
33 int haha()
34 {
35     freopen("interval.in","r",stdin);
36     freopen("interval.out","w",stdout);
37     scanf("%d%d",&n,&m);
38     for(int i=1;i<=n;i++)
39     {
40         p[i]=i;districts &d=ques[i];
41         scanf("%d%d",&d.l,&d.r);
42         d.len=d.r-d.l+1;
43         b[++cnt]=d.l;b[++cnt]=d.r;
44     }
45     sort(p+1,p+n+1,cmp);sort(b+1,b+cnt+1);
46     cnt=unique(b+1,b+cnt+1)-b-1;
47     for(int i=1;i<=n;i++)
48     {
49         int t=p[i];districts &d=ques[t];
50         d.l=lower_bound(b+1,b+cnt+1,d.l)-b;
51         d.r=lower_bound(b+1,b+cnt+1,d.r)-b;
52     }
53     int ans=0x7f7f7f7f;
54     for(int i=1,j=0;j<n||(mx[1]==m&&j==n);)
55     {
56         while(mx[1]<m&&j<n)
57         {
58             j++;
59             Modify(1,1,cnt,ques[p[j]].l,ques[p[j]].r,1);
60         }
61         while(mx[1]==m&&i<=n)
62         {
63             ans=min(ans,ques[p[j]].len-ques[p[i]].len);
64             Modify(1,1,cnt,ques[p[i]].l,ques[p[i]].r,-1);
65             i++;
66         }
67     }
68     if(ans==0x7f7f7f7f)ans=-1;
69     printf("%d\\n",ans);
70 }
71 int sb=haha();
72 int main(){;}
cogs2406

ZJOI2004 树的果实

挖坑……

HNOI2016 序列

挖坑……

cogs2582 动物城的鸳鸯蛋传说

链接:http://cogs.pro/cogs/problem/problem.php?pid=2582

题意:有两个数列,问用第一个数列能组出第二个数列中哪些数。

bitset第一题……

1 http://cogs.pro/cogs/problem/problem.php?pid=2582
cogs2582

cogs2089 平凡的测试数据

出门左转:http://www.cnblogs.com/Loser-of-Life/p/7236695.html

cogs1000 伊吹萃香

出门左转:http://www.cnblogs.com/Loser-of-Life/p/7237419.html

NOI2014 起床困难综合症

链接:http://cogs.pro/cogs/problem/problem.php?pid=1684

题意:一路位运算,求最大攻击伤害。

对每一位进行处理,在m范围内能大伤害就大伤害,相同就在这一位取0。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int haha()
 7 {
 8     freopen("sleep.in","r",stdin);
 9     freopen("sleep.out","w",stdout);
10     int n,m;scanf("%d%d",&n,&m);
11     int id,ide=0;for(id=1;id<m;id=id<<1|1);
12     for(int i=1;i<=n;i++)
13     {
14         char opt[5];int v;scanf("%s%d",opt,&v);
15         switch(opt[0])
16         {
17             case \'O\':ide|=v;id|=v;break;
18             case \'X\':ide^=v;id^=v;break;
19             case \'A\':ide&=v;id&=v;break;
20         }
21     }
22     bool judge=0;int q=0;
23     for(int i=29;i>=0;i--)
24     {
25         int t=ide>>i&1;
26         if((judge||(m>>i&1))&&(id>>i&1)>t)t=id>>i&1;
27         if(m>>i&1)judge=1;
28         q|=t<<i;
29     }
30     printf("%d\\n",q);
31 }
32 int sb=haha();
33 int main(){;}
cogs1684

cogs2235 烤鸡翅

出门左转:http://www.cnblogs.com/Loser-of-Life/p/7236721.html

HEOI2017 期末考试

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4868

题意:有一些人等成绩,每超过预期一天会增加学生不满度,减少判卷时间会增加老师不满度(⊙﹏⊙)b……求最低总不满度。

通过一顿乱搞可以得出总不满度关于时间的函数是一个严格的凹函数,三分时间,求最小值水之。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const int maxn=100005;
 8 int A,B,C;int n,m,t[maxn],b[maxn];
 9 LL work(int val)
10 {
11     LL res=0,v1=0,v2=0;
12     for(int i=1;i<=n;i++)
13         if(val>t[i])res+=(LL)(val-t[i])*C;
14     for(int i=1;i<=m;i++)
15         if(b[i]<val)v1+=val-b[i];
16         else v2+=b[i]-val;
17     if(A>=B)res+=(LL)v2*B;
18     else
19     {
20         res+=(LL)min(v1,v2)*A;
21         if(v1<v2) res+=(LL)(v2-v1)*B;
22     }
23     return res;
24 }
25 int haha()
26 {
27     scanf("%d%d%d",&A,&B,&C);
28     scanf("%d%d",&n,&m);
29     int maxx=0;
30     for(int i=1;i<=n;i++)scanf("%d",&t[i]);
31     for(int i=1;i<=m;i++)scanf("%d",&b[i]);
32     int l=0,r=100000;
33     LL ans=1e18;
34     while(r-l>5)
35     {
36         int mid=l+(r-l)/3,midmid=r-(r-l)/3;
37         LL v1=work(mid),v2=work(midmid);
38         if(v1<=v2) 
39         {
40             ans=min(ans,v1);
41             r=midmid;
42         }
43         else
44         {
45             ans=min(ans,v2);
46             l=mid;
47         }
48     }
49     for(int i=l;i<=r;i++)ans=min(ans,work(i));
50     printf("%lld\\n",ans);
51 }
52 int sb=haha();
53 int main(){;}
bzoj4869

51nod1597 有限背包计数问题

挖坑……

cogs1825 道路和航线

链接:http://cogs.pro/cogs/problem/problem.php?pid=1825

题意:一张带权混合图,保证无向边权值非负,有向边保证不会带来环,求1号节点到所有节点最短路。

我们知道,非负权图可以用Dijkstra保证时间复杂度在$O(nlogn)$,而有向图可以用记忆化搜索保证线性时间复杂度。那么想法就出现了:将每一个无向图中连通块缩成一个点,再进行记忆化搜索。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<queue>
  7 using namespace std;
  8 const int maxt=25005,maxr=50005;
  9 struct node
 10 {
 11     int from,to,weight,next;
 12 }edge1[maxr<<1];
 13 int head1[maxt],tot,t,r,p,s,cnt;
 14 void addedge1(int u,int v,int w)
 15 {
 16     edge1[++tot]=(node){u,v,w,head1[u]};head1[u]=tot;
 17 }
 18 vector<int>a[maxt];
 19 int id[maxt];
 20 void dfs1(int x)
 21 {
 22     id[x]=cnt;a[cnt].push_back(x);
 23     for(int i=head1[x];i;i=edge1[i].next)
 24         if(!id[edge1[i].to])dfs1(edge1[i].to);
 25 }
 26 vector<int>G[maxt],W[maxt],G2[maxt];
 27 int entrance_degree[maxr];
 28 bool vis[maxr];
 29 void dfs2(int x)
 30 {
 31     vis[x]=1;
 32     for(int i=0;i<G2[x].size();i++)
 33     {
 34         entrance_degree[G2[x][i]]++;
 35         if(!vis[G2[x][i]])dfs2(G2[x][i]);
 36     }
 37 }
 38 struct point
 39 {
 40     int dis,id;
 41     bool operator <(const point &b)const{
 42         return dis>b.dis;
 43     }
 44 };
 45 priority_queue<point>heap;
 46 int dist[maxt];
 47 void Dijkstra()
 48 {
 49     while(!heap.empty())
 50     {
 51         point tmp=heap.top();heap.pop();
 52         int dis=tmp.dis,iden=tmp.id;
 53         if(vis[iden])continue;
 54         vis[iden]=1;
 55         for(int i=head1[iden];i;i=edge1[i].next)
 56         {
 57             int v=edge1[i].to;
 58             if(dist[v]>dist[iden]+edge1[i].weight)
 59 2021年11月的做题记录

l洛谷 P3926 SAC E#1 - 一道不可做题 Jelly

Eratosthenes筛选法

用筛选法求100之内的素数

用数组求素数

2018暑期做题部分整合