洛谷P2580(板子题)
原题链接
直接套用板子,将flag改为int型,0表示未出现,输出WRONG,1表示第一次出现输出OK并将其变为2,2输出REPEAT
代码如下
/*********************************************************************/
/**********************************cyf*******************************/
/*******************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,x) for(int i=0;i
#define ll long long
#define repp(i,x) for(int i=1;i<=x;i++)
#define repx(i,n,j) for(int i=j;i
const ll mod=1e9+7;
bool shushu(int x)
{
int flag=0;
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
flag=1;
break;
}
}
if(flag)
return false;
else
return true;
}
int gcd(int x,int y)
{
int t;
while(y%x!=0)
{
t=y%x;
y=x;
x=t;
}
return x;
}
int lcm(int x,int y)
{
return x/gcd(x,y)*y;
}
ll q_pow(ll a,ll b,int m)//
{
ll r=1,base=a;
while(b!=0){
if(b%2)
r*=base;
r%=m;
base*=base;
base%=m;
b/=2;
}
return r;
}
const int maxn=2e6+5;
int totle;
int tree[maxn][30];
int flag[maxn];
void init_(char*str)
{
int len=strlen(str),root=0,id;
rep(i,len)
{
id=str[i]-'a';
if(!tree[root][id])
tree[root][id]=++totle;
root=tree[root][id];
}
flag[root]=1;
}
void find_(char*str)
{
int len=strlen(str),root=0,id;
rep(i,len)
{
id=str[i]-'a';
if(!tree[root][id])
{
cout<<"WRONG"<<endl;
return;
}
root=tree[root][id];
}
if(flag[root]==1)
{
cout<<"OK"<<endl;
flag[root]=2;
}
else
cout<<"REPEAT"<<endl;
}
char s[maxn];
int main()
{
int n,m;
cin>>n;
repp(i,n)
{
cin>>s;
init_(s);
}
cin>>m;
repp(i,m)
{
cin>>s;
find_(s);
}
return 0;
}
洛谷P5149
先用字典树按第一个顺序,求出每个老师的编号,然后就要求第二个顺序中逆序个数,此时可用归并排序,当a[i]>a[j],ans+=mid-i,ans要开ll,不然最后四个测试点会wa代码如下
/*********************************************************************/
/**********************************cyf*******************************/
/*******************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,x) for(int i=0;i
#define ll long long
#define repp(i,x) for(int i=1;i<=x;i++)
#define repx(i,n,j) for(int i=j;i
const ll mod=1e9+7;
bool shushu(int x)
{
int flag=0;
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
flag=1;
break;
}
}
if(flag)
return false;
else
return true;
}
int gcd(int x,int y)
{
int t;
while(y%x!=0)
{
t=y%x;
y=x;
x=t;
}
return x;
}
int lcm(int x,int y)
{
return x/gcd(x,y)*y;
}
ll q_pow(ll a,ll b,int m)//
{
ll r=1,base=a;
while(b!=0){
if(b%2)
r*=base;
r%=m;
base*=base;
base%=m;
b/=2;
}
return r;
}
const int maxn=2e6+5;
int tree[maxn][60];
int flag[maxn];
int totle=0,js=0;
ll ans;
void init_(char*str)
{
int root=0,id,len=strlen(str);
rep(i,len)
{
if(str[i]>='a' && str[i]<='z')
id=str[i]-'a';
else
id=str[i]-'A'+'z'-'a'+1;
if(!tree[root][id])
tree[root][id]=++totle;
root=tree[root][id];
}
flag[root]=++js;
}
int find_(char*str)
{
int root=0,id,len=strlen(str);
rep(i,len)
{
if(str[i]>='a' && str[i]<='z')
id=str[i]-'a';
else
id=str[i]-'A'+'z'-'a'+1;
root=tree[root][id];
}
return flag[root];
}
void hb(int*s,int l,int mid,int r)
{
int b[100005];
int i=l,j=mid,k=0;
while(i<mid && j<=r)
{
if(s[i]<=s[j])
b[k++]=s[i++];
else{
b[k++]=s[j++];
ans+=mid-i;
}
}
while(i<mid) b[k++]=s[i++];
while(j<=r) b[k++]=s[j++];
for(int ii=l;ii<=r;ii++)
s[ii]=b[ii-l];
}
void gb(int*s,int l,int r)
{
if(l==r) return;
int mid=(l+r)/2;
gb(s,l,mid);
gb(s,mid+1,r);
hb(s,l,mid+1,r);
}
char a[10];
int A[100005];
int main()
{
int n;
cin>>n;
ans=0;
repp(i,n)
{
cin>>a;
init_(a);
}
repp(i,n)
{
cin>>a;
A[i]=find_(a);
}
gb(A,1,n);
cout<<ans<<endl;
return 0;
}
洛谷p2922
又是一道板子题
由于说的是暗号和信息最小的为标准,所以查找某条暗号时,从其第一项开始,将每一项中flag数相加,最后一项时,还要额外加上以其为后缀的信息数k(不包括刚好等于的),k=sum[root]-flag[root]
代码如下
/*********************************************************************/
/**********************************cyf*******************************/
/*******************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define rep(i,x) for(int i=0;i
#define ll long long
#define repp(i,x) for(int i=1;i<=x;i++)
#define repx(i,n,j) for(int i=j;i
const ll mod=1e9+7;
bool shushu(int x)
{
int flag=0;
for(int i=2;i*i<=x;i++)
{
if(x%i==0)
{
flag=1;
break;
}
}
if(flag)
return false;
else
return true;
}
int gcd(int x,int y)
{
int t;
while(y%x!=0)
{
t=y%x;
y=x;
x=t;
}
return x;
}
int lcm(int x,int y)
{
return x/gcd(x,y)*y;
}
ll q_pow(ll a,ll b,int m)//
{
ll r=1,base=a;
while(b!=0){
if(b%2)
r*=base;
r%=m;
base*=base;
base%=m;
b/=2;
}
return r;
}
const int maxn=2e6+5;
int tree[maxn][2];
int flag[maxn];
ll sum[maxn];
int totle=0;
void init_(int*str,int len)
{
int root=0,id;
rep(i,len)
{
id=str[i];
if(!tree[root][id])
tree[root][id]=++totle;
root=tree[root][id];
sum[root]+=1;
}
flag[root]+=1;
}
ll find_(int*str,int len)
{
int root=0,id;
ll ans=0;
rep(i,len)
{
id=str[i];
if(!tree[root][id])
return ans;
root=tree[root][id];
ans+=flag[root];
}
ans+=sum[root]-flag[root];
return ans;
}
int a[10005];
int main()
{
int n,m,k;
cin>>n>>m;
repp(i,n)
{
cin>>k;
repp(j,k)
cin>>a[j];
init_(a+1,k);
}
repp(i,m)
{
cin>>k;
repp(j,k)
cin>>a[j];
cout<<find_(a+1,k)<<endl;
}
return 0;
}