時間限制:
4000 ms | 記憶體限制:
65535 kb
難度:4 描述
給你n個數,然後詢問你m次。每次詢問只有兩種情況:
q l r : 輸出l
到r區間內第二大的值(與第一大的值相同的不算第二大)如果沒有第二大的值,輸出-1
s l r k : l到r
區間內,每個值減去k輸入
第1行輸入n,m. 0
輸出對於每個q操作,輸出答案。保證所有資料在int範圍內(那為什麼還把值弄得那麼大呢?(~ ̄▽ ̄)~)
樣例輸入
5 6 1 1 1 2 3 q 1 3 q 4 5 q 4 4 s 1 1 1 q 1 3 q 1 5
樣例輸出
-12-102
**cszdlt
上傳者
傳說中的藍天
如過是找出最大的就是用線段樹寫,找出第二的也是可以用線段樹寫, 每個節點存兩個值乙個為最大值 ,乙個為次大值,這樣父親節點的最大值就是左右兩個兒子較大的那個,次大值就是左右兩個兒子 最大的和次大的4 個數中不同於最大值的那個值。
#includeusing namespace std;
const int n = 100010;
const int ing = 0x3f3f3f3f;
const int inf = -ing;
int ma[n<<2];
int mx[n<<2];
int add[n<<2];
int a[n];
bool cmp(int f ,int g)
void push_up(int rt)
else if(t[1]b?a:b;
}void push_down(int rt)
}void update(int l,int r,int l,int r,int rt,int k)
push_down(rt);
int mid = (l+r)>>1;
if(l<=mid)
update(l,r,l,mid,rt<<1,k);
if(r>mid)
update(l,r,mid+1,r,rt<<1|1,k);
push_up(rt);
}int query1(int l ,int r ,int l ,int r ,int rt)
push_down(rt);
int mid = (l+r)>>1;
int k = inf;
int g = inf;
if(l<=mid)
k = query1(l ,r ,l ,mid,rt<<1);
if(r>mid)
g = query1(l ,r ,mid+1,r, rt<<1|1);
return max (k,g);
}int query(int l ,int r ,int l ,int r ,int rt)
push_down(rt);
int w[5];
for(int i = 1 ; i<=4; i++)
w[i] = inf;
int mid = (l+r)>>1;
int fg = inf;
int ans = inf;
if(l<=mid)
if(r>mid)
if(w[3]!=fg)
ans = max(ans,w[3]);
if(w[4]!=fg)
ans = max(ans,w[4]);
if(l<=mid)
if(r>mid)
return ans;
}void bulid(int l,int r,int rt)
add[rt] = 0;
int mid = (l+r)>>1;
bulid(l,mid,rt<<1);
bulid(mid+1,r,rt<<1|1);
push_up(rt);
}char s[10];
int main()
else}}
return 0;
}
第二大整數
問題描述 編寫乙個程式,讀入一組整數 不超過 20個 當使用者輸入 0時,表示輸入結束。然後程式將從這組整數中,把第二大的那個整數找出來,並把它列印出來。說明 1 0表示輸入結束,它本身並不計入這組整數中。2 在這組整數中,既有正數,也可能有負數。3 這組整數的個數不少於2個。輸入格式 輸入只有一行...
找出陣列中第二大的數
給你乙個陣列,求出其中第二大的數 比如陣列a 1,2,3,4,5,6,7,8,9 其中第二大的數為8,返回8即可 分析 一般情況下都是求最大值,呵呵,這道題很有趣。想想也不難,可以在掃瞄最大值的同時,求出第二大的值,就是比當前最大值大的數賦給最大值,然後用第二大的值與先前的最大值比較,如果小,則用先...
找出陣列中第二大的數
include include includeusing namespace std 初始化最大值為a 0 次大值為a 1 遍歷一次,每次比較並更新最大值和次大值,最後就可以得到次大值。這種方法時間複雜度為o n bool invalidinput false int findsecondmax i...