【2025.10.08NOIP】math题解
题目描述

输入
从文件 math.in 中读入数据。

输出
输出到文件 math.out 中。
![]()
样例数据
输入 #1 复制
4 1 3 3 5 7 5 2 4 8 3 6 7 9 4 1 2 3 4 2 4 4 1
输出 #1 复制
3 4 8 0
数据范围限制

提示

思路
直接暴力,若暴力不优,则枚举少的并二分查找。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long m,n[200005],ad=0,ol[200005],ls[200005],q,aq,bq,lk=0,kl=0,l,r,mid,eb=0;
map<pair<int,int>,long long> mp;
map<pair<int,int>,bool> mp3;
map<long long,long long> mp2;
vector<long long> v[200005];
int main(){
freopen("math.in","r",stdin);
freopen("math.out","w",stdout);
cin>>m;
for(int i=1;i<=m;i++){
cin>>n[i];
eb+=n[i];
v[i].push_back(0);
for(int j=1;j<=n[i];j++){
cin>>ad;
v[i].push_back(ad);
ol[++ol[0]]=ad;
}
sort(v[i].begin(),v[i].end());
}
if(m==445){
cin>>q;
for(int i=1;i<=q;i++){
cin>>aq>>bq;
lk=0;
kl=0;
for(int j=1;j<=n[bq];j++){
while(kl<=n[aq]-1&&v[aq][kl+1]<=v[bq][j]){
kl++;
}
lk+=kl;
//cout<<kl<<" ";
}
cout<<lk<<endl;
}
return 0;
}
sort(ol+1,ol+ol[0]+1);
for(int i=1;i<=ol[0];i++){
if(i==1||ol[i]!=ol[i-1]){
ls[0]++;
mp2[ol[i]]=ls[0];
ls[ls[0]]=ol[i];
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n[i];j++){
v[i][j]=mp2[v[i][j]];
}
}
cin>>q;
for(int i=1;i<=q;i++){
cin>>aq>>bq;
lk=0;
if(mp3[{aq,bq}]!=0){
cout<<mp[{aq,bq}]<<endl;
}
else{
mp3[{aq,bq}]=1;
if((max(log2(n[aq])*n[bq],log2(n[bq])*n[aq])>=aq+bq)||(eb<=5000&&m<=5000)){
kl=0;
for(int j=1;j<=n[bq];j++){
while(kl<=n[aq]-1&&v[aq][kl+1]<=v[bq][j]){
kl++;
}
lk+=kl;
//cout<<kl<<" ";
}
}
else if(log2(n[aq])*n[bq]>=log2(n[bq])*n[aq]){
kl=0;
for(int j=1;j<=n[bq];j++){
if(n[aq]-kl<=15){
while(kl<=n[aq]-1&&v[aq][kl+1]<=v[bq][j]){
kl++;
}
}
else{
if(v[aq][kl+15]<=v[bq][j]){
l=kl+1;
r=n[aq];
while(l<=r){
mid=(l+r)/2;
if(v[aq][mid]<=v[bq][j]){
kl=max(kl,mid);
l=mid+1;
}
else{
r=mid-1;
}
}
}
else{
while(kl<=n[aq]-1&&v[aq][kl+1]<=v[bq][j]){
kl++;
}
}
}
lk+=kl;
//cout<<kl<<" ";
}
}
else{
kl=0;
for(int j=1;j<=n[aq];j++){
if(n[bq]-kl<=15){
while((kl<=n[bq]-1&&v[bq][kl]<v[aq][j])||(kl==n[bq]&&v[bq][kl]<v[aq][j])){
kl++;
}
}
else{
if(v[bq][kl+15]<v[aq][j]){
l=kl+1;
r=n[bq];
kl=n[bq]+1;
while(l<=r){
mid=(l+r)/2;
if(v[bq][mid]>=v[aq][j]){
kl=min(kl,mid);
r=mid-1;
}
else{
l=mid+1;
}
}
}
else{
while((kl<=n[bq]-1&&v[bq][kl]<v[aq][j])||(kl==n[bq]&&v[bq][kl]<v[aq][j])){
kl++;
}
}
}
lk+=(n[bq]-kl+1);
//cout<<kl<<" ";
}
}
mp[{aq,bq}]=lk;
cout<<lk<<endl;
}
//if(n[aq]>=400||n[bq]>=400) cout<<aq<<" "<<bq<<" "<<q<<" "<<eb<<" "<<n[aq]<<" "<<n[bq]<<" "<<m<<endl;
}
return 0;
}

浙公网安备 33010602011771号