注意long long 这种精度问题,
1.这题注意到数据越界,一般有long long 的题目都会很淫荡啊。。。。。
注意poww和rev这两种算逆元的函数,poww更容易越界,但是poww更好用。。因为简单。。
2.注意x>=sum而不是x==sum还有y有也一样
hdu5768
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
struct nodee
{
ll ai, pi;
};
nodee formunal[100];
int t, n;
ll x, y;
void rev(ll a, ll b, ll &x, ll &y,ll mod)
{
if (b == 0)
{
x = 1; y = 0;
return;
}
else
{
rev(b, a%b, y, x, mod);
y -= (a/b)*x;
y = ((y%mod) + mod) % mod;
}
}
ll poww(ll a, ll times, ll mod)
{
ll value = 1; ll temp = a;
while (times)
{
if (times & 1)
{
value *= temp;
value %= mod;
}
times >>= 1;
temp *= temp;
temp %= mod;
}
return value%mod;
}
ll gao(int value)
{
int temp = value;
ll tempmod = 1;
int add = 0;
for (int i = 0; i < n; i++)
{
int q = 1 << i;
if (temp&q)
{
tempmod *= formunal[i].pi;
add++;
}
}
ll sum = 0;
for (int i = 0; i < n; i++)
{
int q = 1 << i;
ll tempmod1 = tempmod;
ll tempmod2=0;
if (temp&q)
{
ll rev1, rev2;
tempmod1 /= formunal[i].pi;
rev(tempmod1, formunal[i].pi, rev1, rev2, formunal[i].pi);
//tempmod2= poww(tempmod1, formunal[i].pi - 2, formunal[i].pi);
tempmod2 = ((rev1%formunal[i].pi)+formunal[i].pi)%formunal[i].pi;
tempmod2 = (tempmod2*formunal[i].ai) % formunal[i].pi;
tempmod2 *= tempmod1;
}
sum += tempmod2;
sum %= tempmod;
}
ll ans = 0;
ans -= x / tempmod;
sum %= tempmod;
if (x%tempmod >= sum)
ans--;
ans += y / tempmod;
if (y%tempmod >= sum)
ans++;
if (add % 2)
ans = ans*(-1);
return ans;
}
/*
4 1 99999999
*/
int main()
{
//rev(3, 13, x, y, 13);
//cout << x<< endl;
//cout << poww(2, 4, 11) << endl;
scanf("%d", &t);
int k = 1;
while (t--)
{
scanf("%d%lld%lld", &n,&x,&y);
//cout << x << " " << y << endl;
x--;
x = x / 7; y = y / 7;
for (int i = 0; i < n; i++)
{
ll ai,pi;
scanf("%lld%lld", &pi, &ai);
ll temp = 7 % pi;
temp = poww(temp, pi - 2, pi);
temp *= ai;
temp %= pi;
formunal[i].pi = pi;
formunal[i].ai = temp;
}
int value = 1;
for (int i = 1; i <= n; i++)
{
value *= 2;
}
value--;
ll ans = y - x;
for (int i = 1; i <= value; i++)
{
ans+=gao(i);
}
printf("Case #%d: %lld\n", k++, ans);
}
}
hdu5769此题还没做出来,下面是错误做法
后缀自动机怎么不可做?
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
struct nodee
{
int son[26];
int fa,pos,maxx;
//char value;
};
nodee tree[300200];
int t,tot;
char s[100100];
char cc[10];
int maxx,noww;
void insert(char c)
{
int tempp = noww;
noww = tot;
if (c== cc[0])
{
tree[noww].pos = maxx;
}
//tree[noww].value = c;
int kind = c - 'a';
if (tree[noww].pos == 0)
tree[noww].pos = tree[tempp].pos;
tree[noww].maxx = maxx;
while (tempp&&tree[tempp].son[kind] == 0)
tree[tempp].son[kind] = noww,
tempp=tree[tempp].fa;
if (tempp == 0 && tree[tempp].son[kind]==0)
tree[tempp].son[kind] = noww,
tree[noww].fa = tempp;
else
{
int nextt = tree[tempp].son[kind];
if (tree[nextt].maxx - 1 == tree[tempp].maxx)
tree[noww].fa = nextt;
else
{
int neww = ++tot;
tree[neww] = tree[nextt];
tree[neww].maxx = tree[tempp].maxx + 1;
if (tree[nextt].maxx == tree[nextt].pos)
tree[neww].pos = tree[tempp].maxx + 1;
else
tree[neww].pos = tree[tempp].pos;
while (tempp&&tree[tempp].son[kind] == nextt)
tree[tempp].son[kind] = neww;
if (tempp == 0 && tree[tempp].son[kind] == nextt)
tree[tempp].son[kind] = neww;
tree[noww].fa = neww; tree[nextt].fa = neww;
}
}
tot++;
maxx++;
}
int main()
{
scanf("%d", &t);
int k = 1;
while (t--)
{
for (int i = 0; i <=tot; i++)for (int j = 0; j < 26; j++)tree[i].son[j] = 0, tree[i].fa = 0, tree[i].pos = 0,tree[i].maxx=0;
tot = 1; maxx = 1; noww = 0;
scanf("%s", cc);
scanf("%s", s);
//cc[0] = (rand() % 26) + 'a';
//for (int i = 0; i < 100000; i++)
//s[i] = (rand() % 26) + 'a';
int len = strlen(s);
//len = 100000;
for (int i = 0; i < len; i++)
{
insert(s[i]);
}
ll sum = 0;
for (int i = tot - 1; i >= 1; i--)
{
int fa = tree[i].fa;
sum += min(tree[i].maxx - tree[fa].maxx, tree[i].pos);
}
printf("Case #%d: %lld\n",k++,sum);
}
}