傳送門qaq
首先有乙個套路(我自己總結的,錯了別罵窩 qwq):
統計滿足類似 \(i \lt j \lt k\) 且 \(a_i \lt a_j \lt a_k\) 的關係的 \((i,j,k)\) 數量的這類題一般來說突破點都是中間的 \(j\),並且一般會採用單調棧處理。
這道題的預處理就是這個套路:
首先對於每個 \(i\),求出左邊離 \(i\) 最近的滿足 \(a_ \gt a_i\) 的 \(l_i\) 和右邊離 \(i\) 最近的滿足 \(a_\gt a_i\) 的 \(r_i\),這個過程可以用單調棧 \(o(n)\) 實現。
然後分別考慮兩種貢獻:
首先將詢問 \((l,r)\) 按照字首和拆分成 \(l-1\) 和 \(r\) 兩部分,這樣前後字首和相減就是 \([l,r]\) 中的貢獻。
考慮每種情況的貢獻如何處理:
遇到 \(r_i\) 時,對 \(l_i\) 產生 \(p_1\) 的貢獻。
遇到 \(l_i\) 時,對 \((i,r_i)\) 產生 \(p_2\) 的貢獻。遇到 \(r_i\) 時,對 \((l_i,i)\) 產生 \(p_2\) 的貢獻。
將貢獻也存入陣列中,讓貢獻和詢問分別按位置公升序排序。
最後用類似 hh的項鍊 的方式一邊遍歷詢問一邊更進貢獻,用乙個樹狀陣列實現區間修改即可。時間複雜度 \(o(n\log n)\)
#include #include #include using namespace std;
const int maxn = 200005;
typedef long long ll;
int n,m,a[maxn];
struct query
query(int l,int r,int x,int v,int id):l(l),r(r),x(x),v(v),id(id){}
bool operator < (const query& p)const
}q[maxn << 2],s[maxn << 2];
int cnt,tot;
int stk[maxn],top = 0,l[maxn],r[maxn];
ll ans[maxn],p1,p2;
ll sum1[maxn],sum2[maxn];
int lowbit(int x)
void add(int x,int y)
return ;
}ll query(int x)
return ans;
}int main()
stk[top = 0] = n + 1;
for(int i = n;i;-- i)
for(int i = 1;i <= m;++ i)
sort(q + 1 , q + 1 + cnt);
for(int i = 1;i <= n;++ i)
sort(s + 1 , s + 1 + tot);
for(int i = 1,j = 1;i <= cnt;++ i)
ans[q[i].id] += 1ll * q[i].v * (query(q[i].r) - query(q[i].l - 1));
} for(int i = 1;i <= m;++ i)printf("%lld\n",ans[i]);
return 0;
}
完結撒花✿✿ヽ(°▽°)ノ✿ 題解 AHOI HNOI2017 影魔
毒瘤了乙個下午。首先這個題是裂開的,就算乙個 p 1 和 p 2 的係數就好了。先轉化一下題意,設區間 i,j 中的最大值為 m 那麼 p 1 的係數就是滿足 m le min 的 i,j 點對的個數,p 2 的係數就是滿足 min m max 的點對個數。然後這個第乙個子任務是沒有意義的,然後考慮...
AHOI HNOI2018 轉盤 解題報告
可能是我語文水平不太行.首先可以猜到一些事實,這個策略一定可以被乙個式子表示出來,不然帶修修改個錘子。然後我們發現,可以列舉起點,然後直接往前走,如果要等就等到它出現。因為如果不等,一定要走超過一圈,這樣一定不如從它後面那個點當起點。既然要等,不如我們就在起點等了,顯然這樣的等價的,於是我們可以搞出...
物件導向部分 201
小夥伴們,還在為不知道怎麼下手而頭疼嗎,我們程式競賽協會來幫你們啦 啦啦啦。另外,如果有對程式設計含有濃厚興趣的同學,我們隨時歡迎你們的加入喲 策劃 譚兆飛 程式設計 管懷文 協助 一號人員要求給她打碼 乾脆二號也打碼好了o o 其實只是提供了題目啦 物件導向部分 201 include inclu...