想了一下就想出了log^2的,之後剛了乙個下午嘗試去掉乙個log結果發現把set改成優先佇列就過了
log^2的自然做法:
彈棧就單點查詢,把經過的所有區間內時間最大的彈掉,第二大的就是新的值
彈掉之後下傳,注意只需要下傳乙個標記,往下一共有log個區間
時間是log^2的,用優先佇列即可通過並且不是最慢
題解乙個log的自然做法:
簡單自然
log^2
#include #define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (ab?a:b)
#define ll long long
//#define file
using namespace std;
int n,m,tp,tp,i,j,k,l,x,y,z,ans,t,find;
char st[21],ch;
struct type find2;
bool operator < (type a,type b)
} void change(int t,int l,int r,int x,int y,int s)
down(t*2,mid-l+1),down(t*2+1,r-mid);
if (x<=mid) change(t*2,l,mid,x,y,s);
if (midtr[2000001];
void change(int t,int l,int r,int x,int y,type s)
if (x<=mid) change(t*2,l,mid,x,y,s);
if (midfind2.t) find=t,find2=s;
} if (l==r) return;
if (x<=mid) find(t*2,l,mid,x);
else find(t*2+1,mid+1,r,x);
} void change(int t,int l,int r,int x,type s)
else
}} t2;
void read(int &x)
void write(int x) while (x) st[++i]=x%10+'0',x/=10; while (i) putchar(st[i--]);putchar('\n');}
int main()
case 2:;
t2.find(1,1,n,x);
t1.change(1,1,n,x,x,find2.x);
}
break;
}case 3:);
break;
}} }
fclose(stdin);
fclose(stdout);
return 0;
}
UOJ 218 UNR 1 火車管理
維護一顆主席樹 火車入棧相當於區間修改,彈棧相當於返回歷史版本 維護線段樹區間求和 ps 之前沒把 放上來 extra的最後乙個點re,orz蒟蒻無能為力 include include include include include const int maxn 600005 const int ...
UOJ 218 UNR 1 火車管理
注意記憶體有些卡,有一些技巧 1.首先對於查詢的線段樹是全域性的,不需要動態開點 2.對於線段樹中的乙個節點 x 如果它的左右兒子都沒有兒子,那麼下一次做區間覆蓋時,就不需要對 x 新建兩個節點 include define lo o 1 define ro o 1 1 using namespac...
uoj218 火車管理 主席樹
維護乙個棧,每次區間壓棧,單點彈棧,區間詢問棧頂的元素和。如果沒有彈棧的操作的話,我們每一次只需要在一顆線段樹上面區間賦值即可。加上彈棧操作,我們每次就需要知道當前棧頂元素的上乙個元素是什麼,考慮用主席樹來維護每乙個時刻每乙個位置的最近一次的修改位置。假設當前的時間為x且我們需要彈棧,那麼我們需要先...