QOJ.ac
QOJ
The 2nd Universal Cup Finals is coming! Check out our event page, schedule, and competition rules!
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#137000 | #244. Turn Off The Light | Delay_for_five_minutes | 100 ✓ | 978ms | 51336kb | C++20 | 4.2kb | 2023-08-09 16:33:02 | 2023-08-09 16:33:11 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
char s[1000005];
int a[1000005];
int ans[2][1000005];
int sm[1000005] , contri[1000005];
int Lmost , Rmost;
int get_even()
{
for(int i = 0;i <= n;i++) {
if(s[i] == '0') a[i] = 0;
else a[i] = 2;
}
sm[0] = a[0];
for(int i = 1;i <= n;i++) sm[i] = (a[i] - sm[i - 1] + 4) % 4;
int sol = 0;
for(int i = 0;i <= n - 1;i++) {
// printf("CUR %d %d\n",i,sm[i]);
if(sm[i] == 0) {
if(i >= Lmost && i < Rmost) sol += (contri[i] = 4);
else contri[i] = 0;
}
else sol += (contri[i] = sm[i]);
}
if(sm[n ] == 0) return sol;
return 1e9;
}
int sol[2][1000005];
int s2[5][1000005];
void cls() {
for(int i = 0;i <= n;i++) sol[0][i] = sol[1][i] = 0;
for(int i = 0;i <= n;i++) s2[0][i] = s2[1][i] = s2[2][i] = s2[3][i] = s2[4][i] = 0;
}
int cal_in(int x)
{
int ans;
if(s[x] == '0') ans= (3 - a[x] + 4) % 4;
else ans = (1 - a[x] + 4) % 4;
if(ans == 3) return -1;
return ans;
}
int cal_out(int x)
{
int ans;
if(s[x] == '0') ans = (1 - a[x] + 4) % 4;
else ans = (3 - a[x] + 4) % 4;
if(ans == 3) return -1;
return ans;
}
void get_odd(int *sans)
{
int ct = sm[n ];
for(int ad_od = -2 ; ad_od <= 2;ad_od ++) {
int cur_ans = 0;
for(int i = n - 1;i >= 0;i--) {
int d = sm[i];
if(i & 1) d += ad_od;
else d -= ad_od;
d = (d + 4) % 4;
if(d == 0) cur_ans += 4;
else cur_ans += d;
// cur_ans -= contri[i];
s2[ad_od + 2][i] = cur_ans ;
// printf("s2 %d , %d %d\n",i,ad_od,s2[ad_od + 2][i]);
}
}
for(int t = 0;t < 2;t++) { ///t 1表示奇数位增加1,偶-1 , t 0表示奇数位-1,偶+1
int x = t * 2 - 1 ; ///+1 / -1
int cur_ans = 0;
sol[t][n + 1] = 1e9;
for(int i = n ;i >= 0;i--) {
int delta = x, de = cal_in(i);
if(i & 1) delta += de;
else delta -= de;
int c1 = sm[i];
if(i & 1) c1 = (c1 + x);
else c1 = (c1 - x);
c1 = (c1 + 4) % 4;
if(c1 == 0) c1 = 4;
sol[t][i] = sol[t][i + 1] + c1;
int du = ct;
if(n & 1) du += delta;
else du -= delta;
if((4 + du) % 4 == 0) {
// printf("ok on %d %d , %d %d\n",i,delta , x , cal_in(i));
sol[t][i] = min(sol[t][i] , s2[delta + 2][i]);
// printf("from i %d , x %d , %d\n",i,x,sol[t][i]);
}
// printf("i %d , x %d , %d\n",i,x,sol[t][i]);
}
}
int sum_c = 0;
for(int i = 0;i <= n;i++) {
int delta = cal_out(i);
if(!(i & 1)) delta = -delta;
//printf("Delta %d %d\n",i,delta);
sans[i] = sum_c + sol[(delta + 1) / 2][i ];
sum_c += contri[i];
}
}
void make_ans(int d)
{
cls();
Lmost = 1e9 , Rmost = -1e9;
for(int i = 0;i < n;i++) {
if(s[i] == '1') Lmost = min(Lmost , i) , Rmost = max(Rmost , i);
}
if(Lmost > Rmost) {
for(int i = 0;i < n;i++) ans[d][i] = 0;
return;
}
int rn = n;n = Rmost;
int sol = get_even();
// cout << "SOL " << sol << '\n';
get_odd(ans[d]) ;
for(int i = Lmost;i <= n;i++) ans[d][i] = min(ans[d][i] , sol) ;
for(int i = n + 1;i < rn;i++) ans[d][i] = 1e9;
if(Lmost == Rmost) ans[d][Lmost] = 3;
n = rn ; return;
}
void solve()
{
const int mod = 1e9 + 7;
cin >> n;
cin >> s;
make_ans(0); //exit(0);
for(int i = 0;i < n - i - 1;i++) swap(s[i] , s[n - i - 1]);
make_ans(1);
int ss = 0;
for(int i = 0;i < n;i++) {
int z = min(ans[0][i] , ans[1][n - i - 1]);
//printf("i %d %d\n",i + 1 , z);
ss = (ss + 1LL*z*(i + 1)) % mod;
}
cout << ss << '\n';
}
int main()
{
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ios::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0);
int t;cin >> t;
while(t--) {
solve();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 978ms
memory: 51336kb
input:
146645 2 00 2 10 2 01 2 11 3 000 3 100 3 010 3 110 3 001 3 101 3 011 3 111 4 0000 4 1000 4 0100 4 1100 4 0010 4 1010 4 0110 4 1110 4 0001 4 1001 4 0101 4 1101 4 0011 4 1011 4 0111 4 1111 5 00000 5 10000 5 01000 5 11000 5 00100 5 10100 5 01100 5 11100 5 00010 5 10010 5 01010 5 11010 5 00110 5 10110 5...
output:
0 5 7 6 0 14 10 12 14 24 12 26 0 34 22 36 18 40 20 38 26 60 40 58 24 62 42 60 0 69 47 66 33 80 50 83 31 90 60 93 34 87 57 80 45 120 90 123 64 117 87 110 42 123 93 120 67 118 88 129 0 123 89 126 63 128 86 125 49 150 108 147 70 153 111 152 51 168 126 165 88 171 129 170 54 165 123 168 85 154 112 159 73...
result:
ok 146645 lines