日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2017西安交大ACM小学期数据结构 [线段树]

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2017西安交大ACM小学期数据结构 [线段树] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Problem B+

發布時間: 2017年7月1日 02:08?? 最后更新: 2017年7月1日 02:10?? 時間限制: 1000ms?? 內存限制: 64M

描述

給定一個長度為n的序列a1,?a2, ...,?an, 滿足這個序列是一個1~n的排列

如果一個序列滿足: 將序列排序后, 任意兩個相鄰的元素的差為1, 那么就稱這個序列為"胖虎序列"

給出q個操作, 操作分為兩種

對于形如1?x?y的操作, 交換axay, 滿足1x<yn

對于形如2?x?y的操作, 判斷區間[x,y]內的元素構成的序列是否為一個"胖虎序列", 如果是, 輸出"YES", 否則輸出"NO", 滿足1xyn

9×104n105,?9×104q105

輸入

第一行兩個整數n,?q, 意義如上所述。
第二行n個整數, 表示序列a
接下來q行, 每行第一個數為opt, 之后緊跟兩個數, 意義如上所述。

輸出

對于每個操作2, 輸出答案, 一行一個。

樣例輸入1?復制 5 3 1 2 4 3 5 2 1 3 1 3 4 2 1 3 樣例輸出1 NO YES 這是一道比較有意思的題,題目給出一個1到n的排列,然后兩種操作:

(1)交換任何兩個數

(2)選取一段連續的區間,并判斷能否構成等差數列且 公差為1


判斷等差序列的時候,我們先找到這段序列的最小值以及最大值,然后假設其為等差序列,估計出區間和,然后和維護的真實區間和進行比對,如果相等就是等差序列,否則的話,就不是

我們用到的區間求最大值,最小值以及區間和的數據結構都是線段樹。

代碼:

#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int MAX = 100007; const int INF = 1e9; int st[MAX<<2][3]; int a[MAX]; int n,q; int ops(int a,int b,int op){switch(op){case 0:return max(a,b);case 1:return min(a,b);case 2:return a + b;} } void build(int cur,int l,int r,int op){if(l == r) st[cur][op] = a[l];else{int mid = (r + l) /2;build(cur*2,l,mid,op);build(cur*2+1,mid + 1,r,op);st[cur][op] = ops(st[cur*2][op],st[cur*2+1][op],op);} } void modify(int cur,int l,int r,int pos,int val,int op){if(l == r) st[cur][op] = val;else{int mid = (l + r)/2;if(pos <= mid) modify(cur*2,l,mid,pos,val,op);else modify(cur*2 + 1,mid + 1,r,pos,val,op);st[cur][op] = ops(st[cur*2][op],st[cur*2+1][op],op);} } int query(int cur,int l,int r,int x,int y,int op){if(x <= l && y >= r) return st[cur][op];int mid = (l+r)/2,res = -INF;if(y <= mid) res = query(cur*2,l,mid,x,y,op);else if(x > mid){res = query(cur*2 + 1,mid + 1,r,x,y,op);}else{int ls = query(cur * 2, l, mid, x, y,op); int rs = query(cur * 2 + 1, mid + 1, r, x, y,op); res = ops(ls,rs,op);}return res; } int main(){scanf("%d%d",&n,&q);for(int i = 1;i <= n;i++){scanf("%d",&a[i]);}build(1,1,n,0);build(1,1,n,1);build(1,1,n,2);while(q--){int opt,x,y;scanf("%d%d%d",&opt,&x,&y);if(opt == 1){modify(1,1,n,x,a[y],0);modify(1,1,n,x,a[y],1);modify(1,1,n,x,a[y],2);modify(1,1,n,y,a[x],0);modify(1,1,n,y,a[x],1);modify(1,1,n,y,a[x],2);swap(a[x],a[y]);}else{int ma = query(1,1,n,x,y,0);int mi = query(1,1,n,x,y,1);int s = (ma+mi)*(ma-mi+1)/2;if(s == query(1,1,n,x,y,2)){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}}}return 0; }


總結

以上是生活随笔為你收集整理的2017西安交大ACM小学期数据结构 [线段树]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。