# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1178586 | alexander707070 | Mosaic (IOI24_mosaic) | C++20 | 0 ms | 0 KiB |
#include<bits/stdc++.h>
#define MAXN 200007
using namespace std;
struct event{
int l,r,id;
};
int row1[MAXN];
int row[3*MAXN],suffix[3*MAXN];
int n,q;
vector<event> queries[MAXN];
int a[MAXN];
long long ans[MAXN];
int answer(int l,int r){
return a[l]-a[r+1];
}
void calc_queries(int w){
for(auto s:queries[w]){
ans[s.id]=answer(s.l,s.r);
}
}
vector<long long> solve(){
vector<long long> sol;
for(int i=0;i<q;i++){
sol.push_back(ans[i]);
}
return sol;
}
int t[5007][5007];
int sumx,sumy;
vector<long long> mosaic(vector<int> X, vector<int> Y,vector<int> T, vector<int> B,vector<int> L, vector<int> R){
n=int(X.size());
q=int(T.size());
for(int i:X)sumx+=i;
for(int i:Y)sumy+=i;
if(sumx==0 and sumy==0){
for(int i=0;i<q;i++){
if(B[i]==0)continue;
if(R[i]==0)continue;
if(T[i]==0)T[i]++;
if(L[i]==0)L[i]++;
long long s=(long long) (B[i]-T[i]+1)*(R[i]-L[i]+1);
int extra=0;
if(s%2==1 and (L[i]+T[i])%2==0)extra=1;
ans[i]=s/2+extra;
}
return solve();
}
if(n<=5000){
for(int i=1;i<=n;i++){
t[1][i]=X[i-1];
t[i][1]=Y[i-1];
}
for(int i=2;i<=n;i++){
for(int f=2;f<=n;f++){
if(t[i-1][f]==0 and t[i][f-1]==0)t[i][f]=1;
else t[i][f]=0;
}
}
for(int i=1;i<=n;i++){
for(int f=1;f<=n;f++){
t[i][f]=t[i][f]+t[i-1][f]+t[i][f-1]-t[i-1][f-1];
}
}
for(int i=0;i<q;i++){
int a=T[i]+1,b=L[i]+1,c=B[i]+1,d=R[i]+1;
ans[i]=t[c][d]-t[c][b-1]-t[a-1][d]+t[a-1][b-1];
}
return solve();
}
for(int i=0;i<q;i++){
queries[T[i]].push_back({L[i],R[i],i});
}
for(int i=0;i<n;i++)a[i]=X[i];
for(int i=n-1;i>=0;i--)a[i]+=a[i+1];
calc_queries(0);
if(n==1)return solve();
row1[0]=Y[1];
for(int i=1;i<n;i++){
if(row1[i-1]==0 and X[i]==0)row1[i]=1;
else row1[i]=0;
}
/// here we have row 1
for(int i=0;i<n;i++)a[i]=row1[i];
for(int i=n-1;i>=0;i--)a[i]+=a[i+1];
calc_queries(1);
if(n==2)return solve();
int start=2*n+1,fr=start;
row[start-1]=Y[2];
for(int i=start;i<=start+n-2;i++){
if(row[i-1]==0 and row1[i-start+1]==0)row[i]=1;
else row[i]=0;
}
for(int i=start;i<=start+n-1;i++){
if(row[i]==1){
fr=i; break;
}
}
/// here we have row 2
for(int i=0;i<n;i++)a[i]=row[i+start-1];
for(int i=n-1;i>=0;i--)a[i]+=a[i+1];
calc_queries(2);
if(n==3)return solve();
for(int f=start+n;f>=start-1;f--)suffix[f]=suffix[f+1]+row[f];
for(int i=3;i<n;i++){
start--;
row[start-1]=Y[i];
for(int f=start;f<fr-1;f++){
row[f]=1-row[f-1];
}
for(int f=fr-1;f>=start-1;f--){
suffix[f]=suffix[f+1]+row[f];
}
for(int f=start;f<=fr;f++){
if(row[f]==1){
fr=f; break;
}
}
for(auto s:queries[i]){
ans[s.id]=suffix[s.l+start-1] - suffix[s.r+start];
}
}
return solve();
}
int main(){
//mosaic({1,1,1,0,0,0,1,1,0,1,0,1,1,1,0},{1,1,1,0,0,0,1,1,0,1,0,1,1,1,0},{},{},{},{});
auto yo=mosaic({0,0,0,0,0}, {0,0,0,0,0}, {1, 0}, {4, 3}, {2,0}, {4,3});
for(auto s:yo)cout<<s<<" ";
return 0;
}