9.10题解

T1

考场上有一部分答案算重了,没有判掉,然后就死了,正解是$bitset$乱搞

记录一下每个点能够到达哪些点,然后减去他的直系儿子,就是最后对答案造成的贡献,每个点能够达到的点由他儿子传过来即可,为了避免多次无用搜索,我们从入度为0的点开始搜,这样的话可以尽量的减少重复搜索的点,但同时由于他是有向边,你还是会有点跑两遍,所以判一下,如果已经跑过了没,就不跑了,直接传信息

但是我们会发现,我们就算用$bitset$,依旧会炸空间,考虑优化,他们是按拓扑序分层转移,而我不会,所以我搜了一半,分两次搜,一次只有前一半的点做贡献,一次只有后一半的点做贡献,把答案加起来,多余的贡献就是$n+m$,减掉就好了

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include
 6 #define maxx 61000
 7 #define maxn 31000
 8 #define maxm 100100
 9 using namespace std;
10 int n,m,u,v,js,ans,mid,opt;
11 int head[maxx],to[maxm],xia[maxm],pd[maxx],du[maxx];
12 bitset  a[maxx];
13 vector <int> sou;
14 void add(int x,int y)
15 {
16     to[++js]=y;  xia[js]=head[x];  head[x]=js;  du[y]++;
17 }
18 void dfs(int x)
19 {
20     pd[x]=1;
21     if(!opt&&x<=mid)  a[x][x]=1;
22     if(opt&&x>mid)  a[x][x-mid]=1;
23     for(int i=head[x];i;i=xia[i])
24     {
25         int ls=to[i];
26         if(!pd[ls])  dfs(ls);
27         a[x]|=a[ls];
28     }
29 }
30 int main()
31 {
32 //    freopen("worldline2.in","r",stdin);
33     scanf("%d%d",&n,&m);
34     for(int i=1;i<=m;++i)  {scanf("%d%d",&u,&v);  add(u,v);}
35     for(int i=1;i<=n;++i)
36         if(!du[i])  sou.push_back(i);
37     mid=n/2;
38     for(int i=0;ii)  dfs(sou[i]);
39     for(int i=1;i<=n;++i)  {ans+=a[i].count();  a[i].reset();}
40     memset(pd,0,sizeof(pd));  opt=1;
41     for(int i=0;ii)  dfs(sou[i]);
42     for(int i=1;i<=n;++i)  {ans+=a[i].count();  a[i].reset();}
43     printf("%d\n",ans-m-n);
44     return 0;
45 }
bitset搜一半非常好用

T2

考场上想到了贪心,但是由于$STL$玩的不够溜,没敢用$set$,手动找的转移点,然后就找死了

我想的贪心是找范围最靠近这个节点的电阻,放给他,这样我就会有左端点,右端点两种限制,考虑怎么可以去掉一个,等等,先离散化一下再继续,因为我们需要用范围当下标,离散化之后,把电阻和节点信息全部按左端点从小到大排序,然后扫每一个节点,如果当前有左节点符合条件的电阻,就把右端点扔进$set$里,这样的话$set$里是所有可用电阻,左端点就不会造成限制了,我们就成功去掉了一个限制,在保证左端点合法的$set$中,$lower$_$bound$出最靠左的右端点合法的位置,放满这个节点,或没有可以放在这个节点的电阻之后进入下一个节点即可,由于$set$自动去重,所以需要开个桶看右端点在这个位置的电阻有多少个,或许$multiset$也可以吧

 1 #include
 2 #include
 3 #include
 4 #include
 5 #include<set>
 6 #define maxn 50100
 7 using namespace std;
 8 struct node{
 9     int l,r,num;
10 }nn[maxn],mm[maxn];
11 int lsh[maxn*8],tong[maxn*8];
12 int T,n,m,bj,head,tot,len;
13 set <int> s;
14 inline int read()
15 {
16     int e=0;  char ch=getchar();
17     while(ch<'0'||ch>'9')  ch=getchar();
18     while(ch>='0'&&ch<='9')  {e=(e<<3)+(e<<1)+(ch^48);  ch=getchar();}
19     return e;
20 }
21 bool cmp(const node &a,const node &b)
22 {
23     return a.l<b.l;
24 }
25 void clear()
26 {
27     bj=0;  head=1;  tot=0;  s.clear();
28     memset(nn,0,sizeof(nn));  memset(mm,0,sizeof(mm));
29     memset(lsh,0,sizeof(lsh));  memset(tong,0,sizeof(tong));
30 }
31 int main()
32 {
33     T=read();
34     while(T--)
35     {
36         n=read();  m=read();  clear();
37         for(int i=1;i<=n;++i)
38         {
39             nn[i].l=read();  nn[i].r=read();  nn[i].num=read();
40             lsh[++tot]=nn[i].l;  lsh[++tot]=nn[i].r;
41         }
42         for(int i=1;i<=m;++i)
43         {
44             mm[i].l=read();  mm[i].r=read();  mm[i].num=read();
45             lsh[++tot]=mm[i].l;  lsh[++tot]=mm[i].r;
46         }
47         sort(lsh+1,lsh+tot+1);
48         len=unique(lsh+1,lsh+tot+1)-lsh-1;
49         for(int i=1;i<=n;++i)
50         {
51             nn[i].l=lower_bound(lsh+1,lsh+len+1,nn[i].l)-lsh;
52             nn[i].r=lower_bound(lsh+1,lsh+len+1,nn[i].r)-lsh;
53         }
54         for(int i=1;i<=m;++i)
55         {
56             mm[i].l=lower_bound(lsh+1,lsh+len+1,mm[i].l)-lsh;
57             mm[i].r=lower_bound(lsh+1,lsh+len+1,mm[i].r)-lsh;
58         }
59         sort(nn+1,nn+n+1,cmp);  sort(mm+1,mm+m+1,cmp);
60         for(int i=1;i<=n;++i)
61         {
62             while(mm[head].l<=nn[i].l&&head<=m)
63             {
64                 s.insert(mm[head].r);  tong[mm[head].r]+=mm[head].num;  head++;
65             }
66             while(1)
67             {
68                 if(nn[i].num==0)  break;
69                 set<int>::iterator it=s.lower_bound(nn[i].r);
70                 if(it==s.end())  break;
71                 int ji=min(nn[i].num,tong[*it]);
72                 nn[i].num-=ji;  tong[*it]-=ji;
73                 if(!tong[*it])  s.erase(it);
74             }
75         }
76         for(int i=1;i<=n;++i)
77             if(nn[i].num)  {bj=1;  break;}
78         if(bj)  printf("No\n");
79         else  printf("Yes\n");
80     }
81     return 0;
82 }
View Code

T3

不会做,咕咕咕人类的本质就是咕咕咕

转载于:https://www.cnblogs.com/hzjuruo/p/11626486.html

你可能感兴趣的:(9.10题解)