提交时间:2023-08-14 12:27:28
运行 ID: 98202
#include<bits/stdc++.h> #define int long long using namespace std; const int N = 1e6 + 5; int n, m, p; int a[N]; int s[N]; int l, r; bool f, F; bool b, B; int c[N]; signed main(){ ios::sync_with_stdio(false); cin >> n >> m >> p; for(int i = 1; i <= n; ++ i){ cin >> a[i]; if(a[i] >= p) f = 1; if(a[i] < p) F = 1; if(a[i] > a[i + 1]) b = 1; if(a[i] < a[i + 1]) B = 1; } if(!f){ for(int i = 1; i <= n; ++ i){ s[i] = s[i - 1] + a[i]; } while(m --){ cin >> l >> r; cout << (s[r] - s[l - 1]) % p << '\n'; } return 0; } if(!F){ for(int i = 1; i <= n; ++ i){ a[i] -= p; s[i] = s[i - 1] + a[i]; } while(m --){ cin >> l >> r; cout << s[r] - s[l - 1] << '\n'; } return 0; } if(!b || !B){ if(!B){ for(int i = 1; i <= n; ++ i){ c[i] = a[i]; } for(int i = 1; i <= n; ++ i){ a[i] = c[n - i + 1]; } } int k = n; for(int i = 1; i <= n; ++ i){ if(a[i] >= p){ k = min(k, i); a[i] -= p; s[i] = s[i - 1] + a[i]; } } while(m --){ cin >> l >> r; if(k <= l){ cout << s[r] - s[l - 1] << '\n'; continue; } int sum = 0; for(int i = l; i < k; ++ i){ sum += a[i]; if(sum >= p) sum -= p; } cout << sum + s[r] - s[k - 1] << '\n'; } return 0; } while(m --){ cin >> l >> r; int sum = 0; for(int i = l; i <= r; ++ i){ sum += a[i]; if(sum >= p) sum -= p; } cout << sum << '\n'; } return 0; } /* 性质 A 送十分,CD 估计是对思路有帮助的 先观望 CD 其实本质上没有区别,只是将数列倒了过来 这里讨论 a[i] <= a[i + 1] 的情况 当我们遇到第一个 a[i] >= p 时,明显后面所有的 a[i] 都会 >= p 将它们全部减去 p ,计算时可直接计算前缀和 其他的。。。听天由命罢 */