题解:P14192 [ICPC 2024 Hangzhou R] Fuzzy Ranking
分析
现在本题仅存的题解未给出详细证明,故稍微写一下。
对于
定义两个序列本质相同当且仅当将其中一个任意重排可以得到另一个,考虑证明区间
现在我们令一个断点
AC Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
inline int c(int x)
{
return x*(x-1)/2;
}
void solve()
{
int n,k,q;
cin>>n>>k>>q;
vector<vector<int>> a(k+1);
for(int i=1;i<=k;i++)
{
a[i].push_back(0);
int x;
for(int j=1;j<=n;j++) cin>>x,a[i].push_back(x);
}
set<int> st;
vector<int> pos,d(n+1);
pos.push_back(0);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++) st.insert(a[j][i]);
if(st.size()==i) d[i]=pos.size(),pos.push_back(i);
}
vector<int> sum;
sum.push_back(0);
for(int i=1;i<pos.size();i++) sum.push_back(sum[sum.size()-1]+c(pos[i]-pos[i-1]));
// for(int i=1;i<sum.size();i++) cout<<"sum["<<i<<"]="<<sum[i]<<'\n';
int lastans=0;
while(q--)
{
int id,l,r;
cin>>id>>l>>r;
id=(id+lastans)%k+1;l=(l+lastans)%n+1;r=(r+lastans)%n+1;
int ans=0;
int nl=*lower_bound(pos.begin(),pos.end(),l);
if(nl>=r)
{
cout<<(lastans=c(r-l+1))<<'\n';
continue;
}
int nr=*(--upper_bound(pos.begin(),pos.end(),r));
cout<<(lastans=(c(nl-l+1)+c(r-nr)+sum[d[nr]]-sum[d[nl]]))<<'\n';
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin>>t;
while(t--) solve();
}