abs bzoj-4127
題目大意:給定一棵數,支援鏈加和鏈上權值的絕對值的和。
注釋:$1\le n,m \le 10^5$,$\delta \ge 0$,$|a_i|\le 10^8$。
想法:看完題,以為又是什麼資料結構裸題。然後發現絕對值... ...臥槽?啥jb玩意兒?絕對值?這怎麼加?開始的想法是維護乙個do標記,表示這個區間有沒有負值,如果沒有直接懶標記,如果有,往下走的時候負數取出來,然後二分治... ...不想寫,上網查的題解。我們先樹鏈剖分之後建線段樹。緊接著我們對於一段區間維護乙個小資訊:maxdown。表示這個點所代表的區間中的所有負值中的最大值的絕對值。我們發現所有的增量都是正的,所以每乙個數的正負號只能變動一次並且只能從負號變成正號。所以在區間修改的時候如果這個區間有負值我們就暴力修改即可。
最後,附上醜陋的**... ...
#include #include #include #include #define n 100010
#define lson l,mid,x<<1
#define rson mid+1,r,x<<1|1
using namespace std;
typedef long long ll;
const int inf=1<<30;
int a[n],head[n],to[n<<1],next[n<<1],cnt,fa[n],deep[n],sv[n],bl[n],pos[n],tot,v[n];
int n,val[n<<2],si[n<<2],add[n<<2];
ll sum[n<<2];
void addedge(int x,int y)
void dfs1(int x)
void dfs2(int x,int c)
}void pushup(int x)
void pushdown(int x)
}void build(int l,int r,int x)
int mid=(l+r)>>1;
build(lson),build(rson);
pushup(x);
}void update(int b,int e,int a,int l,int r,int x)
}ll query(int b,int e,int l,int r,int x)
void modify(int x,int y,int z)
ll solve(int x,int y)
int main()
{ int m,opt,x,y,z;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i小結:注意題目中的資料範圍,對於一些比較特殊的性質要發掘並利用。
bzoj 4147 Abs 熟練剖分
題目描述 給定一棵樹,設計資料結構支援以下操作 1 u v d 表示將路徑 u,v 加d 2 u v 表示詢問路徑 u,v 上點權絕對值的和 輸入 第一行兩個整數n和m,表示結點個數和運算元 接下來一行n個整數a i,表示點i的權值 接下來n 1行,每行兩個整數u,v表示存在一條 u,v 的邊 接下...
樹鏈剖分 樹鏈剖分講解
好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...
BZOJ 3306 樹 樹鏈剖分
和bzoj 3083比就是弱化版了。樣例都有點像?include include using namespace std const int n 100005,m n 3,inf 0x7fffffff int read int next m to m head n sz n son n top n ...