BNU 34975 剪纸 折线划分平面问题 大数模拟+规律
|
题目链接:点击打开链接 最多的情况就是每个直线和当前平面的所有直线都相交 设当前有x根直线 则加入一个type0的直线就能产生 x个交点,两个交点间的线段可以把一个平面划分成2个 就能增加x + 1个平面 再推广 若加入typeY 的直线? 先让Y++,表示加入直线的根数 就能增加 (x + 1) * Y - ?(Y-1) 加完后 平面上的直线数就增加了Y :即 x+=Y 所以每次加入 X 根 Y类型的直线 则答案增加的情况就是: Y++; ans += (x +1) *Y - (Y-1) ans += (x +1 + Y) * Y - (Y-1) · · · ans += (x+1 + (X-1)*Y) * Y - (Y-1) 然后化简一下就是 ans += x*Y +1 ans += (x+Y)*Y+1 · · · ans+=(x+(X-1)*Y) *Y +1 发现ans一共加了 X 个1 然后第一部分是 Y * (等差数列) 再化简成 ans += X + Y*( ( x + x+(X-1)*Y ) * X / 2); 这样我们就能O(1) 算出 每增加一次 答案的增值 但是这里取模会出现问题 /2 的情况逆元可能不存在, 但能保证?( x + x+(X-1)*Y ) * X 一定是偶数,所以用个大数直接进行运算。 import java.math.*;
import java.util.*;
import java.io.*;
public class Main {
static BigInteger x1 = new BigInteger("1");
static BigInteger x2 = new BigInteger("2");
public void work() {
int T;
T = cin.nextInt();
while (T-- > 0) {
int n = cin.nextInt();
long mod = cin.nextLong();
long x = 0;
long ans = 1 % mod;
while(n-->0)
{
long X = cin.nextLong(),Y = cin.nextLong();
Y++;
BigInteger now = BigInteger.valueOf(2*x + (X-1)*Y);
now = now.multiply(BigInteger.valueOf(X));
now = now.divide(BigInteger.valueOf(2));
now = now.mod(BigInteger.valueOf(mod));
long tmp = now.longValue();
tmp *= Y; tmp%=mod;
tmp += X; tmp%=mod;
ans += tmp; ans %= mod;
x += X*Y%mod;
x %=mod;
}
ans = ans % mod;
System.out.println(ans);
}
}
Main() {
cin = new Scanner(System.in);
}
public static void main(String[] args) {
Main e = new Main();
e.work();
}
public Scanner cin;
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
