結果
| 問題 |
No.876 Range Compress Query
|
| コンテスト | |
| ユーザー |
tarattata1
|
| 提出日時 | 2019-09-06 22:28:51 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 88 ms / 2,000 ms |
| コード長 | 3,010 bytes |
| コンパイル時間 | 658 ms |
| コンパイル使用メモリ | 77,500 KB |
| 実行使用メモリ | 7,424 KB |
| 最終ジャッジ日時 | 2024-06-24 19:46:41 |
| 合計ジャッジ時間 | 2,390 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 18 |
コンパイルメッセージ
main.cpp: In function ‘int main(int, char**)’:
main.cpp:92:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
92 | scanf("%d%d", &n, &q);
| ~~~~~^~~~~~~~~~~~~~~~
main.cpp:98:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
98 | scanf("%d", &a[i]);
| ~~~~~^~~~~~~~~~~~~
main.cpp:107:14: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
107 | scanf("%d", &t);
| ~~~~~^~~~~~~~~~
main.cpp:110:18: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
110 | scanf("%d%d%d", &l, &r, &x);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~
main.cpp:116:18: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
116 | scanf("%d%d", &l, &r);
| ~~~~~^~~~~~~~~~~~~~~~
ソースコード
#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <list>
#include <iterator>
#include <assert.h>
#pragma warning(disable:4996)
typedef long long ll;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF 9223300000000000000
#define INF 2140000000
const long long MOD = 1000000007;
using namespace std;
const long long INF2 = (((ll)1<<31)-1);
template<class T> class SegTree // 0-indexed
{
private:
int n; // 葉の数
vector<T> data; // ノードの値を持つ配列
T def; // 初期値かつ単位元
T operation(T a, T b) // 区間クエリで使う処理
{
//return min(a, b); // 区間minクエリ
return make_pair(a.first+b.first, a.second+b.second);
}
T update(T a, ll b) // 点更新で使う処理
{
ll tmp=a.second+b;
return make_pair(tmp==0?0:1, tmp); // 加算の場合
//return b; // 更新の場合
}
// 区間[a,b)の総和。ノードk=[l,r)に着目している。
T _query(int a, int b, int k, int l, int r) {
if (r <= a || b <= l) return def; // 交差しない
if (a <= l && r <= b)
return data[k]; // a,l,r,bの順で完全に含まれる
else {
T c1 = _query(a, b, 2 * k + 1, l, (l + r) / 2); // 左の子
T c2 = _query(a, b, 2 * k + 2, (l + r) / 2, r); // 右の子
return operation(c1, c2);
}
}
public:
SegTree(int _n) { // _n:必要サイズ
def = make_pair(0,0); // 初期値かつ単位元
n = 1;
while (n < _n) n *= 2;
data = vector<T>(2 * n - 1, def);
}
// 場所i(0-indexed)の値をxで更新
void change(int i, ll x) {
i += n - 1;
data[i] = update(data[i],x);
while (i > 0) {
i = (i - 1) / 2;
data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
}
}
// [a, b)の区間クエリを実行
T query(int a, int b) {
return _query(a, b, 0, 0, n);
}
// 添字でアクセス
T operator[](int i) {
return data[i + n - 1];
}
};
int main(int argc, char* argv[])
{
int n,q;
scanf("%d%d", &n, &q);
SegTree<pair<int,ll> > S(n);
vector<int> a(n);
int i;
for(i=0; i<n; i++) {
scanf("%d", &a[i]);
}
for(i=1; i<n; i++) {
int tmp=a[i]-a[i-1];
S.change(i, tmp);
}
for(i=0; i<q; i++) {
int t;
scanf("%d", &t);
if(t==1) {
int l,r,x;
scanf("%d%d%d", &l, &r, &x);
S.change(l-1, x);
S.change(r, -x);
}
else {
int l,r;
scanf("%d%d", &l, &r);
auto ans=S.query(l,r);
printf("%d\n", ans.first+1);
}
}
return 0;
}
tarattata1