會議中心
思路
這一題的正解是倍增的,但是由於我太蒟蒻了,所以我選了乙個不算正解但是有可以拿滿分的題目學習思路和我考場上其實差不多,只是我無法實現....
下面我先來介紹幾個陣列的用途
1.s,s陣列代表的是列舉的i時,包括i區間在內最多有多少個區間
2.p陣列,p[i]記錄的是在這一區間和這一區間之前,字典序最小的並且滿足使區間數最多的區間的位置
3.而pr陣列代表的是由哪乙個區間+1轉移過來的...(大概是這個意思,表達能力不是很好)
然後我們就要討論情況了
第一種情況是我們對這個區間有更新,就是說是由這個區間加上它前面的區間可以構成乙個更大的區間總和
第二種情況就是守老本,看上一層得到的解是否依然更加優秀
所以我們就要有不同的處理方式
m是在該區間之前,滿足其r最接近當前區間的l的,然後我們就看
如果:s[m]+1>s[i-1] ,我們就要更新,即p[i]=i,s[i]=s[m]+1;
s[m]+1
但是還有一種情況,就是2者相等,這是我們就要有選擇了,因為我們既然選擇了這個,後面的方案就是確定了的,但是前面的方案我們就要選擇更優的,即字典序更小的
那就是判斷了,具體見**
tips:是由那個點轉移過來的我們要記錄好,到時候判斷更優的時候需要
二分就不要問我了,我也有點小蒙
1 #include2view code#define ll long long
3#define for(i,a,b) for(register int i=a;i<=b;i++)
4#define rof(i,a,b) for(register int i=a;i>=b;i--)
5using
namespace
std;
6const
int n=200000+10;7
intn;
8int
p[n],pr[n],s[n];
9int
q[n];
10struct
s111
a[n];
14bool
cmp(s1 x,s1 y)
1518
intscan()
1923
while(c>='
0'&&c<='9')
24return
as*f;25}
26int
main()
2733 sort(a+1,a+n+1
,cmp);
34 for(i,1
,n)35
43//
現在我們找到了最近的乙個區間
44int f=s[m]+1
;45 pr[i]=p[m];
46if(f>s[i-1]) s[i]=f,p[i]=i;
47else
if(s[i-1]>f) s[i]=s[i-1],p[i]=p[i-1
];48
else
4957
if(a[p1].id//
處理"祖先"相同但當前結點不同
58if(a[p2].ida[p2].id;
59if(min11],p[i]=p[i-1
];60
else s[i]=f,p[i]=i,pr[i]=p[m];61}
62}63int now=p[n],top=0
;64 cout
65while
(now)
6669 sort(q+1,q+top+1
);70 for(i,1,top) cout
71return0;
72 }
P3626 APIO2009 會議中心
題目鏈結 首先需要知道答案的性質 如果一段區間 l r 可以成為答案,那麼他在答案中左面最近區間的右邊界r和右面最近區間左邊界l之間滿足 r 1 l 1之間的最大區間數 r 1 l 1之間的最大區間數 r 1 l 1之間的最大區間數 1 證明 反證法,如果列舉的這一段區間裡有2個區間的話,r 1 l...
APIO2009 搶掠計畫
description siruseri城中的道路都是單向的。不同的道路由路口連線。按照法律的規定,在每個路口都設立了乙個siruseri銀行的atm取款機。令人奇怪的是,siruseri的酒吧也都設在路口,雖然並不是每個路口都設有酒吧。banditji計畫實施siruseri有史以來最驚天動地的a...
APIO2009 搶掠計畫
嘟嘟嘟 這題讀完思路應該馬上就有了。先強連通分量縮點,然後在dag上dp求最長路即可,並且只在有酒吧的點更新答案。但是這樣不一定正確。原因就是拓撲排序是每一次把入度為0的點加入佇列,但對於每乙個點的入度,我們重新建圖的時候也算上了和起點不連通的點的貢獻,導致入度變大,進而導致有些點無法dp到,使答案...