今天真的是状态一点都不好,希望下次加油吧
T1:极好的问题
这道题,如果我们暴力枚举每种情况是会炸掉的,所以我们从 x ∗ y ∗ z x*y*z x∗y∗z m o d mod mod p p p = = = 1 1 1入手,可以发现,这其实可以转化成逆元的形式,我们设 x ∗ y x*y x∗y为 z z z的逆元,再用一个 h a s h hash hash表解决是否出现,就能快速解决,另外要注意, s e t 和 m a p set和map set和map是很慢的,要尽量避免使用,还有可能出现 x ∗ x ∗ y x*x*y x∗x∗y m o d mod mod p p p = 1 =1 =1的情况,要单独处理。
代码:
#include<bits/stdc++.h>
#define int long long
#define db double
#define re register
#define cs const
#define N 15000005
#define mod 11114123
using namespace std;
inline int read()
{
int x=0,f=1;
char ch;
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
int hashh[N],num[N];
int n,w[10005],ans,last,temp,p;
bool mark[10005];
int loca(int b)
{
temp=b%mod+1;
while(hashh[temp]&&hashh[temp]!=b) ++temp;
return temp;
}
void add(int b)
{
temp=loca(b);
if(!hashh[temp]) hashh[temp]=b;
++num[temp];
}
int ni(int a)
{
int ans=1;
int b=p-2;
while(b)
{
if(b&1) ans=ans*a%p;
a=a*a%p;
b/=2;
}
return ans;
}
signed main()
{
n=read();
p=read();
for(re int i=1;i<=n;++i) w[i]=read();
sort(w+1,w+1+n);
for(re int i=1;i<=n;++i)
{
if(w[i]%p==0)
{
mark[i]=1;
continue;
}
int ww=ni(w[i]);
temp=loca(ww);
ans+=num[temp];
if(w[i]==w[i-1]) ans-=last;
last=num[temp];
if(w[i]!=w[i-1])
{
for(re int j=1;j<i;++j)
{
if(mark[j]||w[j]==w[j-1]) continue;
add(w[i]*w[j]%p);
}
}
else if(w[i-1]!=w[i-2]) add(w[i]*w[i]%p);
}
printf("%lld",ans);
}
T2:背包问题
如果没有这个背包的限,其实就是一个二维偏序问题,可是(它有 ),
于是我们可以想到一种贪心来解决背包,即用容量最大的
l
l
l个背包一定是最优的背包安排,所以我们先按重量降序将物品排序,背包按升序排列,再用
2
2
2个
l
o
w
e
r
lower
lower_
b
o
u
n
d
bound
bound,先查找刚好能装此物品的背包,再维护一个单调递减序列即可。
代码:
#include<bits/stdc++.h>
#define ll long long
#define db double
#define re register
#define cs const
#define N 100005
using namespace std;
inline int read()
{
int x=0,f=1;
char ch;
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
struct node
{
int w,v;
}thing[N];
bool cmp(cs node &a,cs node &b)
{
if(a.w!=b.w) return a.w>b.w;
return a.v>b.v;
}
int t,bag[N],n,m,val[N+2000],ans;
int main()
{
t=read();
while(t--)
{
memset(val,0,sizeof(val));
n=read();
for(re int i=1;i<=n;++i) thing[i].w=read(),thing[i].v=read();
m=read();
ans=0;
for(re int i=1;i<=m;++i) bag[i]=read();
sort(bag+1,bag+1+m);
sort(thing+1,thing+1+n,cmp);
for(re int i=1;i<=n;++i)
{
int lcmm=lower_bound(bag+1,bag+1+m,thing[i].w)-bag;
int lcnn=lower_bound(val+1,val+N,thing[i].v)-val;
lcnn=N-lcnn+1;
lcnn=min(lcnn,m-lcmm+1);
ans=max(ans,lcnn);
val[N-lcnn]=max(val[N-lcnn],thing[i].v);
}
printf("%d\n",ans);
}
}
T3:子树问题
咕咕咕!