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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

cf1562D Two Hundred Twenty One

發布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 cf1562D Two Hundred Twenty One 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

cf1562D Two Hundred Twenty One

題意:

定義一個前綴和公式:a1?a2+a3?a4+..=∑i=1n(?1)i?1?aia_{1}-a_{2}+a_{3}-a_{4}+..=\sum_{i=1}^{n}(-1)^{i-1}*a_{i}a1??a2?+a3??a4?+..=i=1n?(?1)i?1?ai?
然后給你一個長度為n的序列,只包含{-1,1}。
然后q次詢問,每次詢問一個區間,問最少刪除區間內多少個數字可以使得區間[l,r]的區間和等于0

題解:

先看簡單版本,只輸出刪除個數。
我們用sum[i]表示題目所給公式的前綴和,通過樣例可以猜出一個結論(具體證明詳見官方題解)

  • 如果區間[l,r]的區間和等于0,刪除個數為0
  • 如果區間和不為0,區間長度為奇數,答案為1
  • 如果區間和不為0,區間長度為偶數,答案為2(可以先刪除第l個,然后區間長度變成奇數,就是第二個情況)
  • 對于區間長度為奇數的,一定存在某個位置pos,l<=pos<=r,使得刪除第pos位后,剩下的區間和為0,pos的前半部分等于后半部分,也就是滿足:
    sum[r]-sum[pos]=sum[pos-1]-sum[l-1]
    移項:
    sum[r]+sum[l-1]=sum[pos]+sum[pos-1]
    根據sum[r]+sum[l-1]的值去二分找sum[pos]+sum[pos-1]
    存下sum[r]+sum[l-1]所對應的所有sum[pos]+sum[pos-1],方便二分去找

    代碼:

    // Problem: D1. Two Hundred Twenty One (easy version) // Contest: Codeforces - Codeforces Round #741 (Div. 2) // URL: https://codeforces.com/contest/1562/problem/D1 // Memory Limit: 512 MB // Time Limit: 2000 ms // Data:2021-09-03 17:12:18 // By Jozky#include <bits/stdc++.h> #include <unordered_map> #define debug(a, b) printf("%s = %d\n", a, b); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll= 1e18; const int INF_int= 0x3f3f3f3f; void read(){}; template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar) {x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...); } template <typename T> inline void write(T x) {if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0'); } void rd_test() { #ifdef LOCALstartTime= clock();freopen("in.txt", "r", stdin); #endif } void Time_test() { #ifdef LOCALendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); #endif } const int maxn= 3e6 + 8; int sum[maxn]; vector<int> vec[maxn]; int len, q; int pos(int l, int r) {int Sum= sum[r] + sum[l - 1] + 2 * len;int Pos= lower_bound(vec[Sum].begin(), vec[Sum].end(), l) - vec[Sum].begin();return vec[Sum][Pos]; } int main() {//rd_test();int t;read(t);while (t--) {read(len, q);string s;cin >> s;for (int i= 0; i < s.length(); i++) {if ((i + 1) % 2 == 0)sum[i + 1]= sum[i] + (s[i] == '+' ? -1 : 1);elsesum[i + 1]= sum[i] + (s[i] == '+' ? 1 : -1);}for (int i= 1; i <= len; i++) {int Sum= sum[i] + sum[i - 1];vec[Sum + 2 * len].push_back(i); //2*len是偏移量}while (q--) {int l, r;read(l, r);if (sum[r] - sum[l - 1] == 0)printf("0\n");else if ((r - l + 1) % 2 == 1) {printf("1\n");printf("%d\n", pos(l, r));}else {printf("2\n");printf("%d %d\n", l, pos(l + 1, r));}}for (int i= 1; i <= len; i++) {int Sum= sum[i] + sum[i - 1];vec[Sum + 2 * len].clear();}}return 0;//Time_test(); }

    總結

    以上是生活随笔為你收集整理的cf1562D Two Hundred Twenty One的全部內容,希望文章能夠幫你解決所遇到的問題。

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