題目大意:
given a sequence a with length n,count how many quadruple (a,b,c,d) satisfies: a≠b
≠c≠d
,1≤a
n,1≤
cn,aa
,ac>ad
'>a≠b≠c≠d,1≤aada≠b≠c≠d,1≤aad.a≠
b≠c≠
d,1≤
an,1≤
cn,aa
,ac>ad
'>a1,
a2⋯a
n'>a1,a2⋯ana1,a2⋯an. 1≤n≤500001≤n≤50000 0≤ai≤1e9a≠
b≠c≠
d,1≤
an,1≤
cn,aa
,ac>ad
'>a1,
a2⋯a
n'>基本思路:a≠
b≠c≠
d,1≤
an,1≤
cn,aa
,ac>ad
'>a1,
a2⋯a
n'>最樸素的思想就是算出所有順序對所有逆序對相乘然後再減去所有有重複元素的結果,最終得到答案;基本思路和樹狀陣列還是一致的;a≠
b≠c≠
d,1≤
an,1≤
cn,aa
,ac>ad
'>a1,
a2⋯a
n'>反思與總結:
之前學線段樹的時候貌似學的太淺了,區間更新的lazy標記沒學,就是那個pushdown函式,這次專門去理解了一下,我的理解是,如果每次都向下找到每個葉節點再操作非常的費時間,解決方法就用個lazy標記(就是我程式裡的add陣列),除非用到每一段,否則不再向下遞迴,指示標記到當前結點,這樣能大大節省時間(詳細的講解看我的線段樹,其實多半都是轉的大佬們的);
**如下:
#include#include#include
#include
#include
using
namespace
std;
typedef
long
long
ll;const
int maxn = 50000+10
;int
arr[maxn],tmp[maxn];
intlx[maxn],rx[maxn],ld[maxn],rd[maxn];
intsum[maxn],num[maxn];
int ans[maxn<<2],add[maxn<<2
];int
n;map
mm;void pushup(int
root)
void build(int l,int r,int
root)
int m=(l+r)>>1
; build(l,m,root
<<1
); build(m+1,r,root<<1|1
); pushup(root);
}void pushdown(int l,int r,int
root)
}void update(int ql,int qr,int l,int r,int
root)
pushdown(l,r,root);
int m=(l+r)>>1
;
if(ql<=m) update(ql,qr,l,m,root<<1
);
if(qr>m) update(ql,qr,m+1,r,root<<1|1
); pushup(root);
}int query(int ql,int qr,int l,int r,int
root)
intmain()
sort(tmp+1,tmp+n+1
); sum[
0]=add[0]=0
;
int cnt=0
;
for(int i=1;i<=n;i++)
else num[cnt]++;
}build(
1,cnt,1
);
for(int i=1;i<=n;i++)
ll res=0
; ll x=0,y=0
;
for(int i=1;i<=n;i++)
res=x*y;
for(int i=1;i<=n;i++)
printf(
"%i64d\n
",res);
}return0;
}
HDU 3333 線段樹 離散化
只查詢區間不同的數的和 思路好題 對查詢離線 不斷的往每個位置插值 並把前面位置的值置為0 每查到乙個右端點 查詢一下 等價操作的轉換 離散化一下 include define mem a,b memset a,b,sizeof a define lson root 1 define rson ro...
HDU1199 離散化線段樹
題目大意 一段長度未知的線段,一種操作 a b c 表示區間 a,b 要塗的顏色,c w塗白色,c b塗黑色,問你最長的白色區間段時多長。解題思路 就快去南京邀請賽了,最近做題超沒狀態,cf rating一直掉,這麼簡單的線段樹離散化居然搞了我乙個晚上,糾結。開始用線段樹區間合併的方法做,wa到死,...
離散化 線段樹
題目 分析 每次1操作會往序列底加first個second,first 和 second 都是最大1e9的資料,每次2操作詢問序列中第first到第second個數的和 一開始就感覺有點像線段樹,輸入資料太大我們可以離線處理把資料離散化下,然後扔到線段樹上,維護兩個陣列 sum 區間數的值的和 nu...